To have clear idea of how beans can be accessed between contexts
There are two types of context in spring
1. Root context (Context's Loaded by ContextLoaderListener)
2. Servlet context (Context's Loaded by DispatcherServlet)
Is beans defined in rootContext are visible in servletContext? - YES
Beans defined in root context is always visible in all servlet contexts by default. for example dataSource bean defined in root context can be accessed in servlet context as given below.
@Configuration
public class RootConfiguration
{
@Bean
public DataSource dataSource()
{
...
}
}
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.pvn.mvctiles")
public class ServletConfiguration implements WebMvcConfigurer
{
@Autowired
private DataSource dataSource;
...
}
Is beans defined in servletContext visible in rootContext - yes*
(Why * in Yes)
1. Initialization of context order is rootContext first and servletContext next.
During initialization of rootContext i.e, in the root context configuration class/xml if you try to get the bean defined in servletContext you will get NULL. (because servletContext is not initialized yet, hence we can say beans not visible/registered during initialization of rootContext)
But you can get beans defined in servletContext after initialization of servletContext(you can get beans through application context)
you can print and confirm it by
applicationContext.getBeanDefinitionNames();
2. If you want to access beans of servlet context in the filter or in the another servlet context, add "org.springframework.web.servlet"
base package to your root config class/xml
@Configuration
@ComponentScan(basePackages = "org.springframework.web.servlet" )
public class RootConfiguration
after adding you can get all below beans from application context
springSecurityConfig
, tilesConfigurer
, themeSource
, themeResolver
, messageSource
, localeResolver
, requestMappingHandlerMapping
, mvcPathMatcher
, mvcUrlPathHelper
, mvcContentNegotiationManager
, viewControllerHandlerMapping
, beanNameHandlerMapping
, resourceHandlerMapping
, mvcResourceUrlProvider
, defaultServletHandlerMapping
, requestMappingHandlerAdapter
, mvcConversionService
, mvcValidator
, mvcUriComponentsContributor
, httpRequestHandlerAdapter
, simpleControllerHandlerAdapter
, handlerExceptionResolver
, mvcViewResolver
, mvcHandlerMappingIntrospector
If you want to get your custom beans in rootContext add base package value to rootContext component scan as given below.
@Configuration
@ComponentScan(basePackages = { "com.your.configuration.package", "org.springframework.web.servlet" })
public class RootConfiguration
Above given configuration will be helpful if you want injected dependency be available in your rootContext and can be accessed in your servlet-filter. For example If you catch exception in filter and want to send error response which is same as response sent by HttpMessageConverter
but it is configured in servletContext, then you may want to access that configured converter to send the same response.
Note this, below autowiring will not work in servlet-filters
@Autowired
private ApplicationContext appContext;
ApplicationContext autowiring will not work in servlet filter, as filters are initialized before spring container got initialized.(Depends on order of your filter and DelegatingProxyFilter)
So, to get applicationContext in filter
public class YourFilter implements Filter
{
private ApplicationContext appContext;
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
Filter.super.init(filterConfig);
appContext = WebApplicationContextUtils.getRequiredWebApplicationContext(filterConfig.getServletContext());
}
}
Hope it gives clear idea of how beans can be accessed between contexts.