代码块1:TransactionProxyFactoryBean:
/**
* Proxy factory bean for simplified declarative transaction handling.
* This is a convenient alternative to a standard AOP
* {@link org.springframework.aop.framework.ProxyFactoryBean}
* with a separate {@link TransactionInterceptor} definition.
*
* <p><strong>HISTORICAL NOTE:</strong> This class was originally designed to cover the
* typical case of declarative transaction demarcation: namely, wrapping a singleton
* target object with a transactional proxy, proxying all the interfaces that the target
* implements. However, in Spring versions 2.0 and beyond, the functionality provided here
* is superseded by the more convenient {@code tx:} XML namespace. See the <a
* href="http://bit.ly/qUwvwz">declarative transaction management</a> section of the
* Spring reference documentation to understand the modern options for managing
* transactions in Spring applications. For these reasons, <strong>users should favor of
* the {@code tx:} XML namespace as well as
* the @{@link org.springframework.transaction.annotation.Transactional Transactional}
* and @{@link org.springframework.transaction.annotation.EnableTransactionManagement
* EnableTransactionManagement} annotations.</strong>
*
* <p>There are three main properties that need to be specified:
* <ul>
* <li>"transactionManager": the {@link PlatformTransactionManager} implementation to use
* (for example, a {@link org.springframework.transaction.jta.JtaTransactionManager} instance)
* <li>"target": the target object that a transactional proxy should be created for
* <li>"transactionAttributes": the transaction attributes (for example, propagation
* behavior and "readOnly" flag) per target method name (or method name pattern)
* </ul>
*
* <p>If the "transactionManager" property is not set explicitly and this {@link FactoryBean}
* is running in a {@link ListableBeanFactory}, a single matching bean of type
* {@link PlatformTransactionManager} will be fetched from the {@link BeanFactory}.
*
* <p>In contrast to {@link TransactionInterceptor}, the transaction attributes are
* specified as properties, with method names as keys and transaction attribute
* descriptors as values. Method names are always applied to the target class.
*
* <p>Internally, a {@link TransactionInterceptor} instance is used, but the user of this
* class does not have to care. Optionally, a method pointcut can be specified
* to cause conditional invocation of the underlying {@link TransactionInterceptor}.
*
* <p>The "preInterceptors" and "postInterceptors" properties can be set to add
* additional interceptors to the mix, like
* {@link org.springframework.aop.interceptor.PerformanceMonitorInterceptor}.
*
* <p><b>HINT:</b> This class is often used with parent / child bean definitions.
* Typically, you will define the transaction manager and default transaction
* attributes (for method name patterns) in an abstract parent bean definition,
* deriving concrete child bean definitions for specific target objects.
* This reduces the per-bean definition effort to a minimum.
*//配置文件
* <pre code="class">
* <bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
* abstract="true">
* <property name="transactionManager" ref="transactionManager"/>
* <property name="transactionAttributes">
* <props>
* <prop key="insert*">PROPAGATION_REQUIRED</prop>
* <prop key="update*">PROPAGATION_REQUIRED</prop>
* <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
* </props>
* </property>
* </bean>
*
* <bean id="myProxy" parent="baseTransactionProxy">
* <property name="target" ref="myTarget"/>
* </bean>
*
* <bean id="yourProxy" parent="baseTransactionProxy">
* <property name="target" ref="yourTarget"/>
* </bean></pre>
*
* @author Juergen Hoeller
* @author Dmitriy Kopylenko
* @author Rod Johnson
* @author Chris Beams
* @since 21.08.2003
* @see #setTransactionManager
* @see #setTarget
* @see #setTransactionAttributes
* @see TransactionInterceptor
* @see org.springframework.aop.framework.ProxyFactoryBean
*/
@SuppressWarnings("serial")
//用于简化声明性事务处理的代理工厂bean。这是标准AOP的一个方便的替代
//注意:下面设置属性的方法的值都是来自与上面给的配置文件的例子模板中
public class TransactionProxyFactoryBean extends AbstractSingletonProxyFactoryBean
implements BeanFactoryAware {
//事务拦截器 见,代码块2
private final TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
@Nullable
//切点,作用:指定在哪里地方进行事务增强,或者说叫做aop增强
private Pointcut pointcut;
/**
* Set the default transaction manager. This will perform actual
* transaction management: This class is just a way of invoking it.
* @see TransactionInterceptor#setTransactionManager
*/
//设置transactioinmanager(平台事务管理器)
//PlatformTransactionManager 是平台事务管理器抽象出来的一个接口,里面只有最基本的方法声明: 提交:commit() 和 回滚:rollback()
//具体执行时会根据数据源的不同,使用不同的platformTransactioinManager的实现类,如:HibernateTransactionmanager(hibernate)、DataSourceTransactioonManager(jdbc)等
//这里可以看到platformTransactionmanager是设置成transactionInterceptor 的一个属性的,所以transactionInterceptor 是事务管理中非常重要的一个对象
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionInterceptor.setTransactionManager(transactionManager);
}
/**
* Set properties with method names as keys and transaction attribute
* descriptors (parsed via TransactionAttributeEditor) as values:
* e.g. key = "myMethod", value = "PROPAGATION_REQUIRED,readOnly".
* <p>Note: Method names are always applied to the target class,
* no matter if defined in an interface or the class itself.
* <p>Internally, a NameMatchTransactionAttributeSource will be
* created from the given properties.
* @see #setTransactionAttributeSource
* @see TransactionInterceptor#setTransactionAttributes
* @see TransactionAttributeEditor
* @see NameMatchTransactionAttributeSource
*/
//设置事务的属性,见,内部代码块1:
public void setTransactionAttributes(Properties transactionAttributes) {
this.transactionInterceptor.setTransactionAttributes(transactionAttributes);
}
/**
* Set the transaction attribute source which is used to find transaction
* attributes. If specifying a String property value, a PropertyEditor
* will create a MethodMapTransactionAttributeSource from the value.
* @see #setTransactionAttributes
* @see TransactionInterceptor#setTransactionAttributeSource
* @see TransactionAttributeSourceEditor
* @see MethodMapTransactionAttributeSource
* @see NameMatchTransactionAttributeSource
* @see org.springframework.transaction.annotation.AnnotationTransactionAttributeSource
*/
//设置事务属性值的源,暂时不介绍
public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
this.transactionInterceptor.setTransactionAttributeSource(transactionAttributeSource);
}
/**
* Set a pointcut, i.e a bean that can cause conditional invocation
* of the TransactionInterceptor depending on method and attributes passed.
* Note: Additional interceptors are always invoked.
* @see #setPreInterceptors
* @see #setPostInterceptors
*/
//设置切点
public void setPointcut(Pointcut pointcut) {
this.pointcut = pointcut;
}
/**
* This callback is optional: If running in a BeanFactory and no transaction
* manager has been set explicitly, a single matching bean of type
* {@link PlatformTransactionManager} will be fetched from the BeanFactory.
* @see org.springframework.beans.factory.BeanFactory#getBean(Class)
* @see org.springframework.transaction.PlatformTransactionManager
*/
@Override
//设置bean工厂
public void setBeanFactory(BeanFactory beanFactory) {
this.transactionInterceptor.setBeanFactory(beanFactory);
}
/**
* Creates an advisor for this FactoryBean's TransactionInterceptor.
*/
@Override
protected Object createMainInterceptor() {
this.transactionInterceptor.afterPropertiesSet();
if (this.pointcut != null) {
return new DefaultPointcutAdvisor(this.pointcut, this.transactionInterceptor);
}
else {
// Rely on default pointcut.
//一般会执行这里,创建一个织入器(通知器)
//见 内部代码块2:new TransactionAttributeSourceAdvisor
return new TransactionAttributeSourceAdvisor(this.transactionInterceptor);
}
}
/**
* As of 4.2, this method adds {@link TransactionalProxy} to the set of
* proxy interfaces in order to avoid re-processing of transaction metadata.
*/
@Override
protected void postProcessProxyFactory(ProxyFactory proxyFactory) {
proxyFactory.addInterface(TransactionalProxy.class);
}
}
内部代码块1:
/**
* Set properties with method names as keys and transaction attribute
* descriptors (parsed via TransactionAttributeEditor) as values:
* e.g. key = "myMethod", value = "PROPAGATION_REQUIRED,readOnly".
* <p>Note: Method names are always applied to the target class,
* no matter if defined in an interface or the class itself.
* <p>Internally, a NameMatchTransactionAttributeSource will be
* created from the given properties.
* @see #setTransactionAttributeSource
* @see TransactionAttributeEditor
* @see NameMatchTransactionAttributeSource
*/
//使用方法名作为键和事务属性设置属性描述符(通过TransactionAttributeEditor解析)的值:例如key = "myMethod", value = "PROPAGATION_REQUIRED,readOnly"。
public void setTransactionAttributes(Properties transactionAttributes) {
NameMatchTransactionAttributeSource tas = new NameMatchTransactionAttributeSource();
tas.setProperties(transactionAttributes);
this.transactionAttributeSource = tas;
}
代码块2:
/**
* AOP Alliance MethodInterceptor for declarative transaction
* management using the common Spring transaction infrastructure
* ({@link org.springframework.transaction.PlatformTransactionManager}).
*
* <p>Derives from the {@link TransactionAspectSupport} class which
* contains the integration with Spring's underlying transaction API.
* TransactionInterceptor simply calls the relevant superclass methods
* such as {@link #invokeWithinTransaction} in the correct order.
*
* <p>TransactionInterceptors are thread-safe.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @see TransactionProxyFactoryBean
* @see org.springframework.aop.framework.ProxyFactoryBean
* @see org.springframework.aop.framework.ProxyFactory
*/
@SuppressWarnings("serial")
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {
......
@Override
@Nullable
//在目标方法执行之前执行,类似于jdk动态代理中的InvocationHandler中的invoke()方法
//见 第23讲
public Object invoke(MethodInvocation invocation) throws Throwable {
// Work out the target class: may be {@code null}.
// The TransactionAttributeSource should be passed the target class
// as well as the method, which may be from an interface.
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// Adapt to TransactionAspectSupport's invokeWithinTransaction...
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
......
}
代码块3:AbstractSingletonProxyFactoryBean 它是TransactionProxyFactoryBean的父类,因为它里面有FactoryBean获取bean的方法:getObject()方法,所以我们要研究这个类
/**
* Convenient superclass for {@link FactoryBean} types that produce singleton-scoped
* proxy objects.
*
* <p>Manages pre- and post-interceptors (references, rather than
* interceptor names, as in {@link ProxyFactoryBean}) and provides
* consistent interface management.
*
* @author Juergen Hoeller
* @since 2.0
*/
@SuppressWarnings("serial")
//产生单例的代理对象。
public abstract class AbstractSingletonProxyFactoryBean extends ProxyConfig
implements FactoryBean<Object>, BeanClassLoaderAware, InitializingBean {
@Nullable
//要代理的目标对象
private Object target;
@Nullable
//目标对象所实现的目标接口(新生成的代理类会实现这些接口)
private Class<?>[] proxyInterfaces;
@Nullable
//前置拦截器(目标方法执行之前执行)
private Object[] preInterceptors;
@Nullable
//后置拦截器(目标方法执行之后执行)
private Object[] postInterceptors;
/** Default is global AdvisorAdapterRegistry. */
private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
@Nullable
//transient 关键字代表不会被序列化
//类加载器,根据前面对jdk的动态代理的介绍知道,新生成的类需要被类加载器所加载(cglib不用???)
private transient ClassLoader proxyClassLoader;
@Nullable
//最终生成的代理对象
private Object proxy;
/**
* Set the target object, that is, the bean to be wrapped with a transactional proxy.
* <p>The target may be any object, in which case a SingletonTargetSource will
* be created. If it is a TargetSource, no wrapper TargetSource is created:
* This enables the use of a pooling or prototype TargetSource etc.
* @see org.springframework.aop.TargetSource
* @see org.springframework.aop.target.SingletonTargetSource
* @see org.springframework.aop.target.LazyInitTargetSource
* @see org.springframework.aop.target.PrototypeTargetSource
* @see org.springframework.aop.target.CommonsPool2TargetSource
*/
public void setTarget(Object target) {
this.target = target;
}
/**
* Specify the set of interfaces being proxied.
* <p>If not specified (the default), the AOP infrastructure works
* out which interfaces need proxying by analyzing the target,
* proxying all the interfaces that the target object implements.
*/
public void setProxyInterfaces(Class<?>[] proxyInterfaces) {
this.proxyInterfaces = proxyInterfaces;
}
/**
* Set additional interceptors (or advisors) to be applied before the
* implicit transaction interceptor, e.g. a PerformanceMonitorInterceptor.
* <p>You may specify any AOP Alliance MethodInterceptors or other
* Spring AOP Advices, as well as Spring AOP Advisors.
* @see org.springframework.aop.interceptor.PerformanceMonitorInterceptor
*/
public void setPreInterceptors(Object[] preInterceptors) {
this.preInterceptors = preInterceptors;
}
/**
* Set additional interceptors (or advisors) to be applied after the
* implicit transaction interceptor.
* <p>You may specify any AOP Alliance MethodInterceptors or other
* Spring AOP Advices, as well as Spring AOP Advisors.
*/
public void setPostInterceptors(Object[] postInterceptors) {
this.postInterceptors = postInterceptors;
}
/**
* Specify the AdvisorAdapterRegistry to use.
* Default is the global AdvisorAdapterRegistry.
* @see org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry
*/
public void setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry) {
this.advisorAdapterRegistry = advisorAdapterRegistry;
}
/**
* Set the ClassLoader to generate the proxy class in.
* <p>Default is the bean ClassLoader, i.e. the ClassLoader used by the
* containing BeanFactory for loading all bean classes. This can be
* overridden here for specific proxies.
*/
public void setProxyClassLoader(ClassLoader classLoader) {
this.proxyClassLoader = classLoader;
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
if (this.proxyClassLoader == null) {
this.proxyClassLoader = classLoader;
}
}
@Override
//见 第22讲-> 代码块1
public void afterPropertiesSet() {
...
}
/**
* Determine a TargetSource for the given target (or TargetSource).
* @param target target. If this is an implementation of TargetSource it is
* used as our TargetSource; otherwise it is wrapped in a SingletonTargetSource.
* @return a TargetSource for this object
*/
protected TargetSource createTargetSource(Object target) {
if (target instanceof TargetSource) {
return (TargetSource) target;
}
else {
return new SingletonTargetSource(target);
}
}
/**
* A hook for subclasses to post-process the {@link ProxyFactory}
* before creating the proxy instance with it.
* @param proxyFactory the AOP ProxyFactory about to be used
* @since 4.2
*/
protected void postProcessProxyFactory(ProxyFactory proxyFactory) {
}
@Override
//获取由FactoryBean创建的bean对象
//这就奇怪了,这里并没有看到创建bean啊?说明Bean在执行这个方法之前就已经创建好了。这时我们会发现这个类本身实现了InitializingBean 这个接口,实现了这个接口
//的类就需要重写afterPropertiesSet()方法,这个方法会在bean实例创建完成并且所有属性的set方法都调用完成,给属性赋值成功后执行。所以我们去看afterPropertiesSet()
//方法就能找到proxy属性设置的代码了
//当然spring中还可以通过在bean中设置initialize属性来设置初始化方法,这个方法会在afterPropertiesSet()执行后执行
public Object getObject() {
if (this.proxy == null) {
throw new FactoryBeanNotInitializedException();
}
return this.proxy;
}
@Override
@Nullable
public Class<?> getObjectType() {
if (this.proxy != null) {
return this.proxy.getClass();
}
if (this.proxyInterfaces != null && this.proxyInterfaces.length == 1) {
return this.proxyInterfaces[0];
}
if (this.target instanceof TargetSource) {
return ((TargetSource) this.target).getTargetClass();
}
if (this.target != null) {
return this.target.getClass();
}
return null;
}
@Override
public final boolean isSingleton() {
return true;
}
/**
* Create the "main" interceptor for this proxy factory bean.
* Typically an Advisor, but can also be any type of Advice.
* <p>Pre-interceptors will be applied before, post-interceptors
* will be applied after this interceptor.
*/
protected abstract Object createMainInterceptor();
}