Java注解scope和TransactionConfiguration经常要在项目中应用,对于scope的使用,我到现在还没有彻底弄明白,虽然我已经研究出是表示多例还是单例,然而我模糊的是何时我该用单例何时用多例,我会混淆,而TransactionConfiguration注解比较简单,用来配置使用哪一个事务管理器。
scope
在Java项目中,该注解表示该类的生命周期,其值为singleton(单例模式)和prototype(多例模式),简单来说,假如现在存在一个OrderService,该类使用单例模式,那么按照如下测试,可以看出
@Service
@Scope
public class OrderService {
public void sayMyName() {
System.out.println("MyName: " + this);
}
}
public static void main(String[] args) {
SpringUtils.getSpringContext();
SpringUtils.getBeansByClassType(OrderService.class).sayMyName();
SpringUtils.getBeansByClassType(OrderService.class).sayMyName();
SpringUtils.getBeansByClassType(OrderService.class).sayMyName();
}
debug日志:
DEBUG 2015-01-14 11:13:05,622 org.springframework.beans.factory.support.AbstractBeanFactory: Returning cached instance of singleton bean 'orderService'
MyName: com.honzh.socket.server.business.test.OrderService@152bdc7
DEBUG 2015-01-14 11:13:05,622 org.springframework.beans.factory.support.AbstractBeanFactory: Returning cached instance of singleton bean 'orderService'
MyName: com.honzh.socket.server.business.test.OrderService@152bdc7
DEBUG 2015-01-14 11:13:05,622 org.springframework.beans.factory.support.AbstractBeanFactory: Returning cached instance of singleton bean 'orderService'
MyName: com.honzh.socket.server.business.test.OrderService@152bdc7
结论:service对象在单例情况下只有1个。
当参数为多例时:
@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class OrderService {
public void sayMyName() {
System.out.println("MyName: " + this);
}
}
public static void main(String[] args) {
SpringUtils.getSpringContext();
SpringUtils.getBeansByClassType(OrderService.class).sayMyName();
SpringUtils.getBeansByClassType(OrderService.class).sayMyName();
SpringUtils.getBeansByClassType(OrderService.class).sayMyName();
}
DEBUG 2015-01-14 11:15:30,648 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory: Finished creating instance of bean 'orderService'
MyName: com.honzh.socket.server.business.test.OrderService@cab854
DEBUG 2015-01-14 11:15:30,648 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory: Creating instance of bean 'orderService'
DEBUG 2015-01-14 11:15:30,648 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory: Finished creating instance of bean 'orderService'
MyName: com.honzh.socket.server.business.test.OrderService@10bbd42
DEBUG 2015-01-14 11:15:30,648 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory: Creating instance of bean 'orderService'
DEBUG 2015-01-14 11:15:30,648 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory: Finished creating instance of bean 'orderService'
MyName: com.honzh.socket.server.business.test.OrderService@1b6772a
结论:prototype状态下,service在获取时会重新加载一个新的对象。
附上SpringUtils类,该类是为了通过applicationContext文件,加载对应的spring组件。
private static ApplicationContext factory;
private SpringUtils() {
};
public synchronized static ApplicationContext getSpringContext() throws BeansException {
if (factory == null) {
factory = new ClassPathXmlApplicationContext("/com/honzh/socket/server/business/applicationContext.xml");
}
return factory;
}
public synchronized static ApplicationContext getSpringContext(String appContextPath) throws BeansException {
if (factory == null) {
factory = new ClassPathXmlApplicationContext(appContextPath);
}
return factory;
}
public static <T> T getBeansByClassType(Class<T> requiredType) {
return factory.getBean(requiredType);
}
TransactionConfiguration
该注解主要是用于管理spring的事务管理器,假如你的applicationContext.xml中对事务是这样配置的
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
那么同样对于Service对象时,假如你有一个需要启用事务Transactional的方法,那么你其实是不需要为该类指定 TransactionConfiguration注解配置的。
如果你xml中的配置,如上,可以满足基本的事务操作,那么是没有必要启用该注解,如果你的xml中配置了多个事务管理器,该service对象需要区分不同的事务管理器,那么你需要通过如下格式启用TransactionConfiguration
@TransactionConfiguration(transactionManager = "transactionManager1", defaultRollback = true)