When container Initialization执行业务处理的方式为以下几种:
1.Listener,例如:ApplicationEventListener,当容器Initialization后会回调实现该接口的方法。
2.Web.xml,使用<sevlet>元素,注册一个Servlet类,在init method中实现相应的处理,如果通过这种方式,不能直接向Servlet中注入依赖,因为该Servlet不属于Spring容器管理,如需被Spring管理,使用@Component注解可交由Spring维护,或者通过获得ApplicationContext容器,来获取相应依赖Bean,此时需要获得ApplicationContext容器,可以通过实现ApplicationContextAware。
public final class SpringContextUtil implements ApplicationContextAware
{
private static ApplicationContext ctx;
public static <T> T getBean(Class<T> clazz ) {
return SpringContextUtil.ctx.getBean(clazz) ;
}
public static Object getBean(String beanName) throws BeansException
{
return SpringContextUtil.ctx.getBean(beanName);
}
public static boolean containsBean(String beanName)
{
return SpringContextUtil.ctx.containsBean(beanName);
}
public static ApplicationContext getApplicationContext()
{
return SpringContextUtil.ctx;
}
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
SpringContextUtil.ctx = ctx;
}
}
3.InitializeBean interface(Spring提供),为实例对象添加BeanPostProcessor后置处理器,当完成Bean初始化后的回调处理。
执行关于数据库业务处理时发现问题,使用Listener的方式,事务不会生效。
applicationContext.xml
<!-- Configuration DataSource -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="{jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="validationQuery" value="SELECT 1" />
</bean>
<!-- Configuration transactionManager -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 声明式事务使用注解 -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- Use of the inteceptor -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="interceptorPoints" expression="execution(* com.matrixframework.panda.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="interceptorPoints" />
</aop:config>
两种方式事务都无法生效,最终采用编程式事务解决:
applicationContext.xml
<!-- Configuration DataSource -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="{jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="validationQuery" value="SELECT 1" />
</bean>
<!-- configuration transactionManager -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- Use the TransactionTemplate -->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"/>
</bean>
InitializeData.java
public class InitializDataService implements InitializingBean {
private static final Logger log = LoggerFactory.getLogger(InitializDataService.class);
@Resource
private JdbcTemplate jdbcTemplate;
@Resource
private TransactionTemplate transactionTemplate;
@Override
public void afterPropertiesSet() throws Exception {
initializeData();
}
public void initializeData() {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
try {
//TODO do something
...
log.debug("initalize data successfull");
} catch (Exception e) {
status.setRollbackOnly(); //When an exception occurs rollback
log.debug("initialize data error:" + e.getMessage(), e);
}
}
});
}
}