第1节 代理对象创建
PS: 查看源码的jar版本为 Spring-beans:5.2.15.release
1.1 AOP基础用例准备
Bean定义
@Component
public class LagouBean {
public void tech(){
System.out.println("java learning......");
}
}
Aspect定义
package com.lagou;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class LagouAspect {
@Pointcut("execution(* com.lagou.*.*(..))")
public void pointcut(){
}
@Before("pointcut()")
public void before() {
System.out.println("before method ......");
}
}
测试用例
/**
* 测试⽤例:Aop 代理对象创建
*/
@Test
public void testAopProxyBuild(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
LagouBean lagouBean = applicationContext.getBean(LagouBean.class);
lagouBean.tech();
}
1.2 时机点分析
我们发现在getBean之前,LagouBean 对象已经产生(即在第一行初始化代码中完成),而且该对象是一个代理对象(Cglib代理对象),我们断定,容器初始化过程中目标bean已经完成了代理,返回代理对象。
1.3 代理对象创建流程
AbstractAutowireCapableBeanFactory#initializeBean
/**
* 初始化Bean
* 包括Bean的后置处理器初始化
* Bean的一些初始化方法的执行init-method
* Bean的实现声明周期相关接口的属性注入
*/
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
// 执行所有的AwareMethods
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//执行所有的BeanPostProcessor#postProcessorBeforeInitialization 初始化之前的处理器方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//这里就开始执行afterPropertiesSet(实现了InitializingBean接口)方法和initMethod
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//整个Bean初始化完成,执行后置处理器方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//循环执行后置处理器
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
创建代理对象的后置处理器AbstractAutoProxyCreator#postProcessAfterInitialization
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
//检查下该类是否已经暴露过(可能已经创建了,比如A依赖B,创建A的时候,就会先创建B
//当真正需要创建B的时候,就没必要在代理一次已经代理过的对象,避免重复创建
Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return this.wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
AbstractAutoProxyCreator#wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//targetSourcedBeans是否包含,说明之间创建过
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
} else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
} else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
//得到所有候选的Advisor,对Advisors的bean的方法双层遍历匹配。最终得到List<Advisor>,即specificInterceptors
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//重点,创建代理对象
Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
AbstractAutoProxyCreator#createProxy
//为指定bean创建代理对象
protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory)this.beanFactory, beanName, beanClass);
}
//创建代理的工作交给ProxyFactory
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
//根据一些情况判断是否要设置 proxyTargetClass = true(强制cglib代理方式)
if (!proxyFactory.isProxyTargetClass()) {
if (this.shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
} else {
this.evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//把指定和通用拦截对象合并,并都是适配成Advisor
Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
//设置参数
proxyFactory.setTargetSource(targetSource);
this.customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (this.advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//上面准备昨晚就开始创建代理
return proxyFactory.getProxy(this.getProxyClassLoader());
}
接下来跟进到ProxyFactory中
public class ProxyFactory extends ProxyCreatorSupport {
public Object getProxy(@Nullable ClassLoader classLoader) {
// 用ProxyFactory创建AopProxy,然后用AopProxy创建Proxy,
// 所以这里重要的是看获取的AopProxy对象是什么
// 然后进去看怎么创建动态代理,提供了两种:jdk proxy,cglib
return this.createAopProxy().getProxy(classLoader);
}
}
ProxyCreatorSupport
//省略了一些代码
public class ProxyCreatorSupport extends AdvisedSupport {
private AopProxyFactory aopProxyFactory;
public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
this.activate();
}
//先获取创建AopProxy的工厂,在由此创建AopProxy
return this.getAopProxyFactory().createAopProxy(this);
}
public AopProxyFactory getAopProxyFactory() {
return this.aopProxyFactory;
}
}
流程就是用AopProxyFactory创建AopProxy,再用AopProxy创建代理对象,这里的AopProxyFactory默认是DefaultAopProxyFactory,看它的createAopProxy方法。
DefaultAopProxyFactory#createAopProxy
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
return new JdkDynamicAopProxy(config);
} else {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
} else {
return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
}
}
}
DefaultAopProxyFactory#hasNoUserSuppliedProxyInterfaces
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
Class<?>[] ifcs = config.getProxiedInterfaces();
return ifcs.length == 0 || ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0]);
}
这里决定创建代理对象用的是JDK Proxy,还是用Cglib了。最简单的从使用方面使用来说:设置proxyTargetClass=true强制使用cglib,什么参数都不设置并且对象类实现了接口则默认用JDK代理,如果没有实现接口则也必须使用cglib。
ProxyFactory#getProxy(java.lang.ClassLoader)
---->CglibAopProxy#getProxy (找到CglibAopProxy作为实现类查看源码)
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
int x;
if (rootClass.getName().contains("$$")) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
Class[] var5 = additionalInterfaces;
int var6 = additionalInterfaces.length;
for(x = 0; x < var6; ++x) {
Class<?> additionalInterface = var5[x];
this.advised.addInterface(additionalInterface);
}
}
this.validateClassIfNecessary(proxySuperClass, classLoader);
//配置 Cglib 增强
Enhancer enhancer = this.createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader && ((SmartClassLoader)classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
Callback[] callbacks = this.getCallbacks(rootClass);
Class<?>[] types = new Class[callbacks.length];
for(x = 0; x < types.length; ++x) {
types[x] = callbacks[x].getClass();
}
enhancer.setCallbackFilter(new CglibAopProxy.ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
//生成代理类。并且创建一个代理类的实例
return this.createProxyClassAndInstance(enhancer, callbacks);
} catch (IllegalArgumentException | CodeGenerationException var9) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() + ": Common causes of this problem include using a final class or a non-visible class", var9);
} catch (Throwable var10) {
throw new AopConfigException("Unexpected AOP exception", var10);
}
}
AOP源码分析方法调用关系记录
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
调⽤
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
调用
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization(后置处理器AbstractAutoProxyCreator完成bean代理对象创建)
调⽤
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
调⽤
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy (在这⼀步把委托对象的aop增强和通用拦截进行合并,最终给代理对象)
调⽤
org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy
调⽤
org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader
)
第2节 声明型事务
声明式事务很⽅便,尤其纯注解模式,仅仅⼏个注解就能控制事务
思考:这些注解都做了什么?
@EnableTransactionManagement @Transactional
2.1 EnableTransactionManagement
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
@EnableTransactionManagement 注解使用@import引入了TransactionManagementConfigurationSelector类,这个类又向容器导入了两个重要的组件。
2.2 加载事务控制组件
-
AutoProxyRegistrar
AutoProxyRegistrar类的registerBeanDefinitions方法中又注册一个组件
AopConfigUtils#registerAutoProxyCreatorIfNecessary
@Nullable
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAutoProxyCreatorIfNecessary(registry, (Object)null);
}
@Nullable
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}
发现最终,注册了一个叫做InfrastructureAdvisorAutoProxyCreator的bean,而这个类是AbstractAutoProxyCreator的子类,实现了SmartInstantiationAwareBeanPostProcessor接口
继承体系结构图如下
它实现了SmartInstantiationAwareBeanPostProcessor,说明是一个后置处理器,而Spring AOP开启的@EnableAspectJAutoProxy时注册的AnnotationAwareAspectJProxyCreator实现的是同一个接口,所以,声明型事是Spring AOP思想的一种应用。
- ProxyTransactionManagementConfiguration组件
@Configuration(
proxyBeanMethods = false
)
@Role(2)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
public ProxyTransactionManagementConfiguration() {
}
@Bean(
name = {"org.springframework.transaction.config.internalTransactionAdvisor"}
)
@Role(2)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) {
//事务增强器
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
//向事务增强器注入属性解析器 transactionAttributeSource
advisor.setTransactionAttributeSource(transactionAttributeSource);
//向事务增强器注入事务拦截器 transactionInterceptor
advisor.setAdvice(transactionInterceptor);
if (this.enableTx != null) {
advisor.setOrder((Integer)this.enableTx.getNumber("order"));
}
return advisor;
}
@Bean
@Role(2)
//属性解析器 transactionAttributeSource
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}
@Bean
@Role(2)
//事务拦截器 transactionInterceptor
public TransactionInterceptor transactionInterceptor(TransactionAttributeSource transactionAttributeSource) {
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(transactionAttributeSource);
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
}
ProxyTransactionManagementConfiguration是一个容器配置类,注册了一个组件transactionAdvisor,称为事务增强器,然后在这个事务增强器中又注入了两个属性:transactionAttributeSource(属性解析器)、transactionInterceptor(事务拦截器)。
- 属性解析器 AnnotationTransactionAttributeSource 部分源码
public class AnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource implements Serializable {
private static final boolean jta12Present;
private static final boolean ejb3Present;
static {
ClassLoader classLoader = AnnotationTransactionAttributeSource.class.getClassLoader();
jta12Present = ClassUtils.isPresent("javax.transaction.Transactional", classLoader);
ejb3Present = ClassUtils.isPresent("javax.ejb.TransactionAttribute", classLoader);
}
private final boolean publicMethodsOnly;
//注解解析器集合
private final Set<TransactionAnnotationParser> annotationParsers;
属性解析器中有个成员变量annotationParsers,是一个集合,可以添加多个注解解析器(TransactionAnnotationParser),我们关注Spring的注解解析器,部分源码如下。
SpringTransactionAnnotationParser#parseTransactionAnnotation
protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
Propagation propagation = (Propagation)attributes.getEnum("propagation");
rbta.setPropagationBehavior(propagation.value());
Isolation isolation = (Isolation)attributes.getEnum("isolation");
rbta.setIsolationLevel(isolation.value());
rbta.setTimeout(attributes.getNumber("timeout").intValue());
rbta.setReadOnly(attributes.getBoolean("readOnly"));
rbta.setQualifier(attributes.getString("value"));
List<RollbackRuleAttribute> rollbackRules = new ArrayList();
Class[] var6 = attributes.getClassArray("rollbackFor");
解析的属性名对应@Transactional的属性,属性解析器作用之一就是用解析@Transaction注解
- transactionInterceptor事务拦截器,部分源码如下
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {
//构造方法传入
public TransactionInterceptor(TransactionManager ptm, TransactionAttributeSource tas) {
this.setTransactionManager(ptm);
this.setTransactionAttributeSource(tas);
}
@Nullable
public Object invoke(MethodInvocation invocation) throws Throwable {
Class<?> targetClass = invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null;
Method var10001 = invocation.getMethod();
invocation.getClass();
//添加事务支持
return this.invokeWithinTransaction(var10001, targetClass, invocation::proceed);
}
}
- 上述注解如何关联起来?
- 事务拦截器实现了MethodInterceptor接口,追溯一下上面提到的InfrastructureAdvisorAutoProxyCreator后置处理器,它会在代理对象执行目标方法的时候获取其拦截器链,而拦截器链就是这个TransactionInterceptor,这就把两个组件联系起来。
- ProxyTransactionManagementConfiguration构造方法传入PlatformTransactionManager(事务管理器)(TransactionManager的子类)、TransactionAttributeSource (属性解析器)但是追溯一下上面贴的ProxyTransactionManagementConfiguration源码,在注册事务拦截器的时候并没有调用这个带参构造方法,而是调用无参构造方法,然后再通过set方法注入这两个属性效果一样。
- invokeWithinTransaction 方法,部分源码如下
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, TransactionAspectSupport.InvocationCallback invocation) throws Throwable {
//获取属性解析器,即在ProxyTransactionManagementConfiguration容器配置类中注册事务拦截器时注入的
TransactionAttributeSource tas = this.getTransactionAttributeSource();
TransactionAttribute txAttr = tas != null ? tas.getTransactionAttribute(method, targetClass) : null;
//获取事务管理器
TransactionManager tm = this.determineTransactionManager(txAttr);
String joinpointIdentification = this.methodIdentification(method, targetClass, txAttr);
try {
retVal = invocation.proceedWithInvocation();
}catch{
//如果目标方法抛异常,会执行completeTransactionAfterThrowing(获取事务管理器,执行回滚操作)
this.completeTransactionAfterThrowing(txInfo, var18);
throw var18;
} finally {
this.cleanupTransactionInfo(txInfo);
}
//如果目标方法正常进行,则会执行commitTransactionAfterReturning(获取事务管理器,执行提交事务操作)
this.commitTransactionAfterReturning(txInfo);
return retVal;
}
声明型事务分析记录
@EnableTransactionManagement注解
- 通过@import引入了TransactionManagementConfigurationSelector类
它的selectImports方法导入了另外两个类:
AutoProxyRegistrar 和 ProxyTransactionManagementConfiguration - AutoProxyRegistrar 类分析方法registerBeanDefinitions中引入了其他类,通过AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry)引入InfrastructureAdvisorAutoProxyCreator,它继承了AbstractAutoProxyCreator,是一个后置处理器类。
- ProxyTransactionManagementConfiguration 是一个添加了@Configuration注解的配置类(注册bean)
注册事务增强器(注入属性解析器、事务拦截器)
- 属性解析器:AnnotationTransactionAttributeSource,内部持有一个解析器集合Set<TransactionAnnotationParser> annotationParsers
具体使用的是SpringTransactionAnnotationParser解析器,用来解析@Transational的事务属性 - 事务拦截器:TransactionInterceptor实现了MethodInterceptor接口,该通用拦截会在产生代理对象之前和aop增强合并,最终一起影响到代理对象。
TransactionInterceptor的invoke方法中invokeWithinTransaction会触发原有业务逻辑调用(增强事务)