<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref local="dataSource"></ref>
</property>
</bean>
<bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="transactionManager" />
</property>
<property name="transactionAttributes">
<props>
<prop key="update">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="service" parent="baseTransactionProxy">
<property name="target">
<ref local="service_target" />
</property>
</bean>
<bean id="service_target" class="test.spring.transaction.TestService" />
以上是spring声明式事务的一种方式。
当调用context.getBean("service"),代理的生成过程是怎样的?
TransactionProxyFactoryBean的父类AbstractSingletonProxyFactoryBean中有个方法afterPropertiesSet,在这个方法中(afterPropertiesSet方法是spring在初始化bean的的过程中,会调用该方法,通过实现该方法,为bean提供一些特定的行为。),会产生一个代理。
public void afterPropertiesSet() {
if (this.target == null) {
throw new IllegalArgumentException("Property 'target' is required");
}
if (this.target instanceof String) {
throw new IllegalArgumentException("'target' needs to be a bean reference, not a bean name as value");
}
if (this.proxyClassLoader == null) {
this.proxyClassLoader = ClassUtils.getDefaultClassLoader();
}
ProxyFactory proxyFactory = new ProxyFactory();
if (this.preInterceptors != null) {
for (Object interceptor : this.preInterceptors) {
proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));
}
}
// Add the main interceptor (typically an Advisor).
proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(createMainInterceptor()));
if (this.postInterceptors != null) {
for (Object interceptor : this.postInterceptors) {
proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));
}
}
proxyFactory.copyFrom(this);
TargetSource targetSource = createTargetSource(this.target);
proxyFactory.setTargetSource(targetSource);
if (this.proxyInterfaces != null) {
proxyFactory.setInterfaces(this.proxyInterfaces);
}
else if (!isProxyTargetClass()) {
// Rely on AOP infrastructure to tell us what interfaces to proxy.
proxyFactory.setInterfaces(
ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass(), this.proxyClassLoader));
}
this.proxy = proxyFactory.getProxy(this.proxyClassLoader);
}
spring 在bean生成之后,判断bean是否为FactoryBean,具体在AbstractBeanFactory的
getObjectForBeanInstance中。
如果是FactoryBean,将使用FactoryBeanRegistrySupport类(DetautListableFactory的父类)中的doGetObjectFromFactoryBean方法
private Object doGetObjectFromFactoryBean(
final FactoryBean factory, final String beanName, final boolean shouldPostProcess)
throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
return factory.getObject();
}
}, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
if (object == null && isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
if (object != null && shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of the FactoryBean's object failed", ex);
}
}
return object;
}
可以看到该方法中
object = factory.getObject();
调用了FactoryBean的getObjcet。
那么从AbstractSingletonProxyFactoryBean(TransactionProxyFactoryBean的父类)中的getObject方法中看到
public Object getObject() {
if (this.proxy == null) {
throw new FactoryBeanNotInitializedException();
}
return this.proxy;
}
方法返回了上面(afterPropertiesSet方法中生成的代理)产生的代理类。
因此getBean获取的是一个代理(jdk代理或cgLib代理)。