24
24
import org .springframework .beans .BeanUtils ;
25
25
import org .springframework .beans .factory .InitializingBean ;
26
26
import org .springframework .context .ApplicationContext ;
27
+ import org .springframework .context .ApplicationContextAware ;
27
28
import org .springframework .lang .Nullable ;
28
29
import org .springframework .util .Assert ;
29
30
import org .springframework .util .PatternMatchUtils ;
57
58
*
58
59
* @author Rossen Stoyanchev
59
60
* @author Sebastien Deleuze
61
+ * @author Juergen Hoeller
60
62
* @since 5.0
61
63
*/
62
- public class UrlBasedViewResolver extends ViewResolverSupport implements ViewResolver , InitializingBean {
64
+ public class UrlBasedViewResolver extends ViewResolverSupport
65
+ implements ViewResolver , ApplicationContextAware , InitializingBean {
63
66
64
67
/**
65
68
* Prefix for special view names that specify a redirect URL (usually
@@ -82,11 +85,13 @@ public class UrlBasedViewResolver extends ViewResolverSupport implements ViewRes
82
85
83
86
private String requestContextAttribute ;
84
87
88
+ private ApplicationContext applicationContext ;
89
+
85
90
86
91
/**
87
- * Set the view class to instantiate through {@link #createUrlBasedView (String)}.
92
+ * Set the view class to instantiate through {@link #createView (String)}.
88
93
* @param viewClass a class that is assignable to the required view class
89
- * which by default is AbstractUrlBasedView.
94
+ * which by default is AbstractUrlBasedView
90
95
*/
91
96
public void setViewClass (Class <?> viewClass ) {
92
97
if (!requiredViewClass ().isAssignableFrom (viewClass )) {
@@ -170,7 +175,7 @@ public void setRedirectViewProvider(Function<String, RedirectView> redirectViewP
170
175
}
171
176
172
177
/**
173
- * Set the name of the RequestContext attribute for all views.
178
+ * Set the name of the {@link RequestContext} attribute for all views.
174
179
* @param requestContextAttribute name of the RequestContext attribute
175
180
* @see AbstractView#setRequestContextAttribute
176
181
*/
@@ -179,13 +184,35 @@ public void setRequestContextAttribute(String requestContextAttribute) {
179
184
}
180
185
181
186
/**
182
- * Return the name of the RequestContext attribute for all views, if any.
187
+ * Return the name of the @link RequestContext} attribute for all views, if any.
183
188
*/
184
189
@ Nullable
185
190
protected String getRequestContextAttribute () {
186
191
return this .requestContextAttribute ;
187
192
}
188
193
194
+ /**
195
+ * Accept the containing {@code ApplicationContext}, if any.
196
+ * <p>To be used for the initialization of newly created {@link View} instances,
197
+ * applying lifecycle callbacks and providing access to the containing environment.
198
+ * @see #setViewClass
199
+ * @see #createView
200
+ * @see #applyLifecycleMethods
201
+ */
202
+ @ Override
203
+ public void setApplicationContext (ApplicationContext applicationContext ) {
204
+ this .applicationContext = applicationContext ;
205
+ }
206
+
207
+ /**
208
+ * Return the containing {@code ApplicationContext}, if any.
209
+ * @see #setApplicationContext
210
+ */
211
+ @ Nullable
212
+ public ApplicationContext getApplicationContext () {
213
+ return this .applicationContext ;
214
+ }
215
+
189
216
190
217
@ Override
191
218
public void afterPropertiesSet () throws Exception {
@@ -207,7 +234,7 @@ public Mono<View> resolveViewName(String viewName, Locale locale) {
207
234
urlBasedView = this .redirectViewProvider .apply (redirectUrl );
208
235
}
209
236
else {
210
- urlBasedView = createUrlBasedView (viewName );
237
+ urlBasedView = createView (viewName );
211
238
}
212
239
213
240
View view = applyLifecycleMethods (viewName , urlBasedView );
@@ -220,10 +247,9 @@ public Mono<View> resolveViewName(String viewName, Locale locale) {
220
247
}
221
248
222
249
/**
223
- * Indicates whether or not this {@link ViewResolver} can handle the
224
- * supplied view name. If not, an empty result is returned. The default
225
- * implementation checks against the configured {@link #setViewNames
226
- * view names}.
250
+ * Indicates whether or not this {@link ViewResolver} can handle the supplied
251
+ * view name. If not, an empty result is returned. The default implementation
252
+ * checks against the configured {@link #setViewNames view names}.
227
253
* @param viewName the name of the view to retrieve
228
254
* @param locale the Locale to retrieve the view for
229
255
* @return whether this resolver applies to the specified view
@@ -238,15 +264,14 @@ protected boolean canHandle(String viewName, Locale locale) {
238
264
* Creates a new View instance of the specified view class and configures it.
239
265
* Does <i>not</i> perform any lookup for pre-defined View instances.
240
266
* <p>Spring lifecycle methods as defined by the bean container do not have to
241
- * be called here; those will be applied by the {@code loadView} method
242
- * after this method returns.
243
- * <p>Subclasses will typically call {@code super.buildView(viewName)}
244
- * first, before setting further properties themselves. {@code loadView}
245
- * will then apply Spring lifecycle methods at the end of this process.
267
+ * be called here: They will be automatically applied afterwards, provided
268
+ * that an {@link #setApplicationContext ApplicationContext} is available.
246
269
* @param viewName the name of the view to build
247
270
* @return the View instance
271
+ * @see #getViewClass()
272
+ * @see #applyLifecycleMethods
248
273
*/
249
- protected AbstractUrlBasedView createUrlBasedView (String viewName ) {
274
+ protected AbstractUrlBasedView createView (String viewName ) {
250
275
Class <?> viewClass = getViewClass ();
251
276
Assert .state (viewClass != null , "No view class" );
252
277
@@ -259,7 +284,19 @@ protected AbstractUrlBasedView createUrlBasedView(String viewName) {
259
284
return view ;
260
285
}
261
286
262
- private View applyLifecycleMethods (String viewName , AbstractView view ) {
287
+ /**
288
+ * Apply the containing {@link ApplicationContext}'s lifecycle methods
289
+ * to the given {@link View} instance, if such a context is available.
290
+ * @param viewName the name of the view
291
+ * @param view the freshly created View instance, pre-configured with
292
+ * {@link AbstractUrlBasedView}'s properties
293
+ * @return the {@link View} instance to use (either the original one
294
+ * or a decorated variant)
295
+ * @see #getApplicationContext()
296
+ * @see ApplicationContext#getAutowireCapableBeanFactory()
297
+ * @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#initializeBean
298
+ */
299
+ protected View applyLifecycleMethods (String viewName , AbstractUrlBasedView view ) {
263
300
ApplicationContext context = getApplicationContext ();
264
301
if (context != null ) {
265
302
Object initialized = context .getAutowireCapableBeanFactory ().initializeBean (view , viewName );
0 commit comments