AOP源码解析

前言

我之前在看源码都是局限于其中一步、两步没有一个整体观,我们在看源码的时候如果能在一个整体观去看,很多时候有些内容就豁然开朗了。

介绍

我们先看一下,整改spring容器启动这个流程,其中AOP 就在 初始化Bean后面由BeanPostProccessor 进行后置处理将Bean替换为AOP的代理类进行操作。
如果我们认识到这一点那么我们就有两个需要重点关注:

第一个是关于BeanPostProccessor 实现类对容器的注入。
第二个是BeanPostProccessor 的实现类对Bean本身代理处理。
在这里插入图片描述

实践

1、贴出一个切面

@Aspect
public class AspectJTest {
 
	@Pointcut("execution(* *.say(..))")
	public void test(){}
	
	@Before("test()")
	public void before(){
		System.out.println("before test..");
	}
	
	@After("test()")
	public void after(){
		System.out.println("after test..");
	}
	
	@Around("test()")
	public Object around(ProceedingJoinPoint p){
		System.out.println("around before");
		Object o = null;
		try {
			o = p.proceed();
		} catch (Throwable e) {
			e.printStackTrace();
		}
		System.out.println("around after");
		return o;
	}
}

2、切入点

public interface Person {
	void say();
}
class Student implements Person {

	@Override
	public void say() {
		System.out.println("这是一个苦逼的程序员");
	}
}

3、bean.xml的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

<aop:aspectj-autoproxy/>
<bean id="student" class="com.megvii.winterolympicvillage.provider.aop.Student"/>
<bean class="com.megvii.winterolympicvillage.provider.aop.AspectJTest"/>
</beans>

4、测试类

public class Test {

	public static void main(String[] args) {

		ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
		Person bean2 = (Person) ac.getBean("student");
		bean2.say();
	}
}

源码解析

我们在调用 ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext(“beans.xml”); 之后会进入我们最常见
AbstractApplicationContext#refresh源码 部分。主要在这个地方对各个部分进行串联。

由前面流程图可知,将解析xml文件获取beanFactory 内容,这一步获取xml中内容,也是这一步注册BeanPostProccessor 到工厂中,对Bean 进行包装。


    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            //刷新前的预处理;
            prepareRefresh();

            //获取BeanFactory;默认实现是DefaultListableBeanFactory,在创建容器的时候创建的(这一步解析BeanDefinitions)
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            //BeanFactory的预准备工作(BeanFactory进行一些设置,比如context的类加载器,BeanPostProcessor和XXXAware自动装配等)
            prepareBeanFactory(beanFactory);

            try {
                //BeanFactory准备工作完成后进行的后置处理工作
                postProcessBeanFactory(beanFactory);

                //执行BeanFactoryPostProcessor的方法;
                invokeBeanFactoryPostProcessors(beanFactory);

                //注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执行
                registerBeanPostProcessors(beanFactory);

                //初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
                initMessageSource();

                //初始化事件派发器
                initApplicationEventMulticaster();

                //子类重写这个方法,在容器刷新的时候可以自定义逻辑;如创建Tomcat,Jetty等WEB服务器
                onRefresh();

                //注册应用的监听器。就是注册实现了ApplicationListener接口的监听器bean,这些监听器是注册到ApplicationEventMulticaster中的
                registerListeners();

                //初始化所有剩下的非懒加载的单例bean
                finishBeanFactoryInitialization(beanFactory);

                //完成context的刷新。主要是调用LifecycleProcessor的onRefresh()方法,并且发布事件(ContextRefreshedEvent)
                finishRefresh();
            }

            ......
    }



源码解析

 获取BeanFactory;默认实现是DefaultListableBeanFactory,在创建容器的时候创建的(这一步解析BeanDefinitions)
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();  会对xml文件进行解析

在这里插入图片描述

        对<aop:aspectj-autoproxy/> 的解析过程中,针对获取元素进行注册。

在这里插入图片描述
在这里插入图片描述

可以看到在解析过程中将对aop:aspectj-autoproxy/ 会将AnnotationAwareAspectJAutoProxyCreator.class 进行注册
我们看一下AnnotationAwareAspectJAutoProxyCreator.class 的集成关系
在这里插入图片描述

可以看到AnnotationAwareAspectJAutoProxyCreator 是继承BeanPostProccessor
那么在Bean 初始化后会对由BeanPostProccessor 进行后置处理将Bean替换为AOP的代理类进行操作。对后面两个bean 的初始化不在这个关心的重点就跳过。

源码解析

在这里插入图片描述
在这里插入图片描述

可以看到在初始之后确实进行aop的后置操作,最终创建DefaultAopProxyFactory进行JDK 代理
在这里插入图片描述

在这里插入图片描述
返回装饰对象AOP对象
在这里插入图片描述

当aop调用数据的时候,使用创建一个调用链,进行调用
在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值