我們先看下這兩個東東的配置方法:
對於contextConfigLocation參數,有2個地方可以配置:
1)context-param 是全局性配置
2)servlet下的init-param 是局部性配置
若以上兩處都設置了一個相同的bean配置文件路徑,那么該文件內配置的bean會被初始化2次,所以一個配置文件
只能選擇一種配置位置;
項目中使用spring框架有2種方式:
1)listener下的ContextLoaderListener 是一種引入方式,默認讀取
/WEB-INF/
applicationContext.xml
2)若是spring-web項目,DispatcherServlet 也是一種引入方式,默認讀取
/WEB-INF/$
{servlet-name}-servlet.xml
倘若以上2種配置都引入了,那么全局性的bean配置文件會被加載2次;而且
2種方式的各自配置文件里的配置項在某種意義上並不是合並互補,而是各成一個體系(雖然普通的bean看似是都加載到全局上下文來了,但還是有一些特殊bean和配置項沒有按預期的那樣工作);
比如
/WEB-INF/
applicationContext.xml
文件下里的AOP聲明式配置:
<!--aop 行為-->
<bean id="himvn" class="com.tangbao.hellomvn.Himvn" />
<!--aop 注釋方式-->
<bean id="hiaspect" class="com.tangbao.hellomvn.Hiaspect" />
<!--aop config-->
<aop:aspectj-autoproxy />
<aop:config>
<aop:aspect id="aoplianxi" ref="himvn">
<aop:pointcut id="test1" expression="execution(* com.tangbao.controller.RestlessController.RestlessController(..))"></aop:pointcut>
<aop:before method="sayHi" pointcut-ref="test1"></aop:before>
<aop:after method="sayHi" pointcut-ref="test1"></aop:after>
</aop:aspect>
</aop:config>
若只是在全局配置項中,而沒有在DispatcherServlet 中加載,那么此aop會無效。
所以,在web項目中,就不要使用ContextLoaderListener 和全局配置
contextConfigLocation參數了,統一在DispatcherServlet 下配置,應該就不那么混亂了。如下:
這樣結果就如我們的預期:多bean配置文件不會出現重復加載,所有aop配置也都生效。
以上論點是在spring4.3.1下親測所得,當然是從表現猜測本質的,還沒有真正去研讀Spring的源碼,所以若有原理說錯之處,還望各位看官指出!
