个人组须要开发一个公共基础Spring配置,来完成多个工程所需的共性配置与功能。但带来的问题则是Spring配置扩展问题,公共的Spring配置当然好,但若是须要扩展某个Bean就有问题了。列举一个典型的例子,如公共模块中LocalSessionFactoryBean已经定义了annotatedClasses列表。但引用公共模块配置的工程但愿在里面加入本身的附加annotatedClasses列表。 html
因为Spring的Xml配置启动时就由于自动按依赖关系加载好须要的依赖Bean。若是想干扰Bean初始化的过程是比较麻烦的,有可能须要编写一些特殊的BeanFactory类来完成。在查阅资料时发现Spring 3中的SpEL功能比较强大,也许能够不用作Java开发经过纯Xml配置来完成我想要的配置。 java
<bean id="annotatedClassesList" class="java.util.ArrayList" > <constructor-arg index="0" value="#{ getBeanFactory().containsBean('otherAnnotatedClassesList') ? @otherAnnotatedClassesList : annotatedClassesEmptyList}" /> </bean> <bean id="annotatedClassesEmptyList" class="java.util.Collections" factory-method="emptyList"/> <bean id="annotatedClassesListAddDefault" factory-bean="annotatedClassesList" factory-method="addAll"> <constructor-arg index="0"> <list> <value>org.noahx.XXXX1</value> <value>org.noahx.XXXX2</value> <value>org.noahx.XXXX3</value> </list> </constructor-arg> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" depends-on="annotatedClassesListAddDefault"> <property name="dataSource" ref="dataSource"/> <property name="annotatedClasses" ref="annotatedClassesList"/> <property name="hibernateProperties"> <props> <prop key="hibernate.show_sql">false</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> </bean>
让咱们经过逆序追踪的方法来看Bean加载过程。 spring
一、sessionFactory中加入了depends-on属性,因此在加载sessionFactory前必先加载annotatedClassesListAddDefault 五、存在则将otherAnnotatedClassesList注入构造函数参数,不存在则将annotatedClassesEmptyList注入构造函数参数
六、这样SpEL就能够决定annotatedClassesList初始化时的结果 sql
<import resource="classpath:org/noahx/xxx/common.xml"></import> <!--引用公共Jar中的Xml配置--> <bean id="otherAnnotatedClassesList" class="java.util.ArrayList" > <constructor-arg index="0"> <list> <value>org.noahx.XXXX4</value> <value>org.noahx.XXXX5</value> </list> </constructor-arg> </bean>
若是项目须要加入本身的classes就能够定义一个otherAnnotatedClassesList。公共类加载时,也会将XXXX4与XXXX5一同加载。若是项目不须要修改持久类,则彻底能够不定义otherAnnotatedClassesList。 express
这样,otherAnnotatedClassesList就变为一个配置扩展点,不须要项目作什么高级的处理。有扩展点加载执行,没有不加载执行。 session
SpEL仍是比较强大的,除了我采用getBeanFactory().containsBean()这样很是规方式来判断Bean是否存外,SpEL还有很是多的特性。它的使用将使咱们的Spring配置具备更强的灵活性。 函数
Spring 4的说明(SpEL):http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/expressions.html spa
注:Spring 3后就可使用SpEL,只是高版本支持的功能更多。 hibernate