古道长亭

Contact me with ixiaoqiang0011@gmail.com


  • 首页

  • 归档

  • 分类

  • 关于

  • Book

  • 搜索

Aop源码剖析

时间: 2022-10-07   |   分类: Spring   | 字数: 2432 字 | 阅读约: 5分钟 | 阅读次数:

Spring AOP源码剖析

一、代理对象创建

1.数据准备

@Component
public class TestBeanAspect {

    public void testAop() {
        System.out.println("---------------------- test aop ---------------------");
    }


}

@Component
@Aspect
public class TestAspect {

    @Pointcut("execution(* com.example.demo.entity.TestBeanAspect.testAop(..))")
    public void pointcut() {

    }

    @Before("pointcut()")
    public void before() {
        System.out.println("---------------------- aop before method --------------------");
    }
}

@Configuration
@ComponentScan({"com.example.demo"})
@EnableAspectJAutoProxy //开启spring对注解aop的支持
public class SpringConfig {

    // @Bean
    // public TestBean getTestBean() {
    //     return new TestBean();
    // }

    @Bean
    public TestAspect testAspect() {
        return new TestAspect();
    }

    @Bean
    public TestBeanAspect testBeanAspect() {
        return new TestBeanAspect();
    }
}


@Test
public void test3() {
  ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
  TestBeanAspect testBean = context.getBean(TestBeanAspect.class);
  testBean.testAop();
}

2.时机点分析

我们发现在 getBean 之前,TestBeanAspect对象已经产⽣(即在第⼀⾏初始化代码中完成),⽽且该对象是⼀个代理对象(Cglib代理对象),我们断定,容器初始化过程中⽬标Ban已经完成了代理,返回了代理对象。

3.代理对象创建流程

  • 由ioc知道,最后初始化bean,位置在AbstractAutowireCapableBeanFactory#initializeBean方法处

  • 进入AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

    循环执行后置处理器,注意aop后置处理器是AnnotationAwareAspectJAutoProxyCreator

  • 创建代理对象的后置处理器AbstractAutoProxyCreator#postProcessAfterInitialization

  • AbstractAutoProxyCreator#wrapIfNecessary

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
    			return bean;
    		}
    		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
    			return bean;
    		}
    		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
    			this.advisedBeans.put(cacheKey, Boolean.FALSE);
    			return bean;
    		}
    
    		// Create proxy if we have advice.
      	//获取所有Advisor 对Advisors和bean的⽅法双层遍历匹配,最终得到⼀个List<Advisor>,即specificInterceptors
    		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    		if (specificInterceptors != DO_NOT_PROXY) {
    			this.advisedBeans.put(cacheKey, Boolean.TRUE);
          //创建代理对象
    			Object proxy = createProxy(
    					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
    			this.proxyTypes.put(cacheKey, proxy.getClass());
    			return proxy;
    		}
    
    		this.advisedBeans.put(cacheKey, Boolean.FALSE);
    		return bean;
    	}
    
  • AbstractAutoProxyCreator#createProxy

    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
        // 如果该值为true,则proxyFactory将会使用CGLIB对目标对象进行代理,默认值为false
    		if (!proxyFactory.isProxyTargetClass()) {
    			if (shouldProxyTargetClass(beanClass, beanName)) {
    				proxyFactory.setProxyTargetClass(true);
    			}
    			else {
    				evaluateProxyInterfaces(beanClass, proxyFactory);
    			}
    		}
    
        // 把指定和通⽤拦截对象合并, 并都适配成Advisor
    		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    		proxyFactory.addAdvisors(advisors);
    		proxyFactory.setTargetSource(targetSource);
    		customizeProxyFactory(proxyFactory);
    
    		proxyFactory.setFrozen(this.freezeProxy);
    		if (advisorsPreFiltered()) {
    			proxyFactory.setPreFiltered(true);
    		}
    		//开始创建代理
    		return proxyFactory.getProxy(getProxyClassLoader());
    	}
    
  • 先创建aop proxy工厂,再创建AopProxy

    protected final synchronized AopProxy createAopProxy() {
    		if (!this.active) {
    			activate();
    		}
    		return getAopProxyFactory().createAopProxy(this);
    	}
    
  • DefaultAopProxyFactory#createAopProxy

    这⾥决定创建代理对象是⽤JDK Proxy,还是⽤ Cglib 了,最简单的从使⽤⽅⾯使⽤来说:设置proxyTargetClass=true强制使⽤Cglib 代理,什么参数都不设并且对象类实现了接⼝则默认⽤JDK 代理,如果没有实现接⼝则也必须⽤Cglib

    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    		if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
    			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.");
    			}
    			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
    				return new JdkDynamicAopProxy(config);
    			}
    			return new ObjenesisCglibAopProxy(config);
    		}
    		else {
    			return new JdkDynamicAopProxy(config);
    		}
    	}
    
  • CglibAopProxy#getProxy(java.lang.ClassLoader

二、Spring 声明式事务控制

声明式事务很⽅便,尤其纯注解模式,仅仅⼏个注解就能控制事务了

思考:这些注解都做了什么?

  • @EnableTransactionManagement
  • @Transactional

1.@EnableTransactionManagement

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {

	boolean proxyTargetClass() default false;

	AdviceMode mode() default AdviceMode.PROXY;

	int order() default Ordered.LOWEST_PRECEDENCE;

}
  • 使⽤ @Import 标签引⼊了TransactionManagementConfigurationSelector类,这个类⼜向容器中导⼊了两个重要的组件

    • AutoProxyRegistrar

    • ProxyTransactionManagementConfiguration

      @Override
      	protected String[] selectImports(AdviceMode adviceMode) {
      		switch (adviceMode) {
      			case PROXY:
      				return new String[] {AutoProxyRegistrar.class.getName(),
      						ProxyTransactionManagementConfiguration.class.getName()};
      			case ASPECTJ:
      				return new String[] {determineTransactionAspectClass()};
      			default:
      				return null;
      		}
      	}
      

2.@Transactional

  • AutoProxyRegistrar

    AutoProxyRegistrar 类的 registerBeanDefinitions ⽅法中⼜注册了⼀个组件**InfrastructureAdvisorAutoProxyCreator**

    @Nullable
    	public static BeanDefinition registerAutoProxyCreatorIfNecessary(
    			BeanDefinitionRegistry registry, @Nullable Object source) {
    
    		return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
    	}
    

    这个类是AbstractAutoProxyCreator 的⼦类,实现了 SmartInstantiationAwareBeanPostProcessor 接⼝

    它实现了SmartInstantiationAwareBeanPostProcessor,说明这是⼀个后置处理器,⽽且跟spring AOP 开启@EnableAspectJAutoProxy 时注册的 AnnotationAwareAspectJProxyCreator实现的是同⼀个接⼝,所以说,声明式事务是 springAOP 思想的⼀种应⽤

  • ProxyTransactionManagementConfiguration

    @Configuration
    public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
    
    	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
    	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
        //事务增强器
    		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
        // 向事务增强器中注⼊ 属性解析器 transactionAttributeSource
    		advisor.setTransactionAttributeSource(transactionAttributeSource());
        // 向事务增强器中注⼊ 事务拦截器 transactionInterceptor
    		advisor.setAdvice(transactionInterceptor());
    		if (this.enableTx != null) {
    			advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
    		}
    		return advisor;
    	}
    
    	@Bean
    	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
      // 属性解析器 transactionAttributeSource
    	public TransactionAttributeSource transactionAttributeSource() {
    		return new AnnotationTransactionAttributeSource();
    	}
    
    	@Bean
    	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
      // 事务拦截器
    	public TransactionInterceptor transactionInterceptor() {
    		TransactionInterceptor interceptor = new TransactionInterceptor();
    		interceptor.setTransactionAttributeSource(transactionAttributeSource());
    		if (this.txManager != null) {
    			interceptor.setTransactionManager(this.txManager);
    		}
    		return interceptor;
    	}
    
    }
    

    ProxyTransactionManagementConfiguration是⼀个容器配置类,注册了⼀个组件transactionAdvisor,称为事务增强器,然后在这个事务增强器中⼜注⼊了两个属性:

    即属性解析器transactionAttributeSource

    和

    事务拦截器transactionInterceptor

    属性解析器有⼀个成员变量是annotationParsers,是⼀个集合,可以添加多种注解解析器(TransactionAnnotationParser),我们关注 Spring 的注解解析器,部分源码如下

    //对@Trasactional注解的解析
    protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
    		RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
    
    		Propagation propagation = attributes.getEnum("propagation");
    		rbta.setPropagationBehavior(propagation.value());
    		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<>();
    		for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
    			rollbackRules.add(new RollbackRuleAttribute(rbRule));
    		}
    		for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
    			rollbackRules.add(new RollbackRuleAttribute(rbRule));
    		}
    		for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
    			rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
    		}
    		for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
    			rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
    		}
    		rbta.setRollbackRules(rollbackRules);
    
    		return rbta;
    	}
    

    TransactionInterceptor 事务拦截器如下

    上述组件如何关联起来的?

    1. 事务拦截器实现了MethodInterceptor接⼝,追溯⼀下上⾯提到的InfrastructureAdvisorAutoProxyCreator后置处理器,它会在代理对象执⾏⽬标⽅法的时候获取其拦截器链,⽽拦截器链就是这个TransactionInterceptor,这就把这两个组件联系起来;

    2. 构造⽅法传⼊PlatformTransactionManager(事务管理器)、TransactionAttributeSource(属性解析器),但是追溯⼀下上⾯贴的ProxyTransactionManagementConfiguration的源码,在注册事务拦截器的时候并没有调⽤这个带参构造⽅法,⽽是调⽤的⽆参构造⽅法,然后再调⽤set⽅法注⼊这两个属性,效果⼀样。

    invokeWithinTransaction方法,源码如下

#Spring# #Aop#
QQ扫一扫交流

标题:Aop源码剖析

作者:古道长亭

声明: 欢迎加群交流!

如有帮助,欢迎多多交流 ^_^

微信打赏

支付宝打赏

zookeeper简介
架构设计基本原则
  • 文章目录
  • 站点概览
古道长亭

古道长亭

Always remember that your present situation is not your final destination. The best is yet to come.

226 日志
57 分类
104 标签
GitHub Gitee
友情链接
  • 古道长亭的BOOK
  • JAVA学习
标签云
  • Mysql
  • 搜索引擎
  • Mybatis
  • 容器
  • 架构
  • 消息队列
  • Flink
  • Sharding sphere
  • 流处理
  • 缓存
  • 一、代理对象创建
    • 1.数据准备
    • 2.时机点分析
    • 3.代理对象创建流程
  • 二、Spring 声明式事务控制
    • 1.@EnableTransactionManagement
    • 2.@Transactional
© 2019 - 2024 京ICP备19012088号-1
0%