定义的注解始终无法生效
现象: 该bean被初始化, 但是在该bean上的注解始终无法生效. debug发现了注解扫描的时候, 没有发现该bean. 通过地址, 发现了多个上下文.
spring mvc框架的多个上下文
使用Spirng MVC 需要很好的理解 框架的上下文.
Spring 定义了多个上下文 使用父子结构. Spring 管理 beans 归属 不同的上下文, org.springframework.context.ApplicationContext 是其他上下文的根.
官方文档:
The interface org.springframework.context.ApplicationContext represents the Spring IoC container and is responsible for instantiating, configuring, and assembling the aforementioned beans. The container gets its instructions on what objects to instantiate, configure, and assemble by reading configuration metadata. The configuration metadata is represented in XML, Java annotations, or Java code. Again there is one more context called WebApplicationContext in Spring MVC, which is a child context. The FrameworkServlet of the spring framework i.e. DispatcherServlet will have this web context.
接口org.springframework.context.ApplicationContext 代表了spring Ioc的容器, 同时为bean的初始化, 装配, 配置负责. 该容器通过读取配置的meta信息来知道哪些对象应该初始化, 配置, 装配.配置meta信息存在xml, java的注解, 或者代码中. 在spring mvc中存在多个上下文, 叫做 WebApplicationContext.它叫做子上下文. spring framework的FrameworkServlet,即 DispatcherServlet有他自己的web上下文.
官方文档:
In the Web MVC framework, each DispatcherServlet has its own WebApplicationContext, which inherits all the beans already defined in the root WebApplicationContext. These inherited beans can be overridden in the servlet-specific scope, and you can define new scope-specific beans local to a given Servlet instance. The ApplicationContext related beans are loaded using one of the two following ways.
在web Mvc 框架中, 每个DispatcherServlet 有它自己的 WebApplicationContext, 每个继承了它的根WebApplicationContext的所有bean. 这些继承的bean可以在指定的servlet-specific 区域. 同时你可以定义新的范围. 关联的 ApplicationContext 可以用以下两种方式被加载.
In web.xml we can have configuration for the org.springframework.web.context.ContextLoaderListener class, which is a servlet context listener in the following way. This listener will get invoked when a web app gets deployed on the server.
ContextLoaderListener configuration:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/application-context.xml</param-value>
</context-param>
This listener looks for a context-param named contextConfigLocation in the web.xml. If it finds one, then the xml meta data file will be scanned for the beans that belong to the root application context. If it doesn’t find any, then the listener will look for a file named applicationContext.xml in the class path for the configuration meta data.
Similarly the DispatcherServlet, which is configured in the web.xml will look for an init-param named contextConfigLocation in the servlet definition as shown below.
DispatcherServlet configuration:
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/spring/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
If the init-param is not configured, then a file named dispatcher-servlet.xml will be searched for in the class path. Tha file name being searched for is made up of the servlet name – in our case ‘dispatcher’ – and a string ‘-servlet.xml’ as suffix.
注意 子上下文 : the MVC context 可以访问父上下文的bean. 但是反之不成立.
所以: 如果 the ContextLoaderListener or in case of DispatcherServlet if the parameters are not found in the web.xml and the corresponding files applicationContext.xml or YOUR SERVLET NAME-servlet.xml are not found in the class path
应用启动的时候将会跑出 FileNotFoundException .
Usually the model classes and other beans that belong to the entire application are configured as beans in the applicationContext.xml. And the classes annotated with @Controller and the beans that are related to the MVC layer are configured in the DispatcherServlet configuration file.
Most of the tutorials on web have Spring MVC configuration with a single file included in both the parent context as well as in the child context because of lack of understanding of how Spring works. Due to this all the beans configured in the corresponding xml file will be instantiated twice including any of those beans defined for connection pooling, in which case connection pooling will also be a problem.
If we have only one file with spring beans configuration meta data, then we can configure only that xml file in DispatcherServlet‘s web context, which is the only mandatory context for an MVC web application, in which case we can exclude the configuration for the servlet context listener ContextLoaderListener in the web.xml.