AOP源码解析

前言

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

介绍

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

第一个是关于BeanPostProccessor 实现类对容器的注入。
第二个是BeanPostProccessor 的实现类对Bean本身代理处理。
AOP源码解析_第1张图片

实践

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的配置文件


<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源码解析_第2张图片

 的解析过程中,针对获取元素进行注册。

AOP源码解析_第3张图片
AOP源码解析_第4张图片

可以看到在解析过程中将对aop:aspectj-autoproxy/ 会将AnnotationAwareAspectJAutoProxyCreator.class 进行注册
我们看一下AnnotationAwareAspectJAutoProxyCreator.class 的集成关系
AOP源码解析_第5张图片

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

源码解析

AOP源码解析_第6张图片
AOP源码解析_第7张图片

可以看到在初始之后确实进行aop的后置操作,最终创建DefaultAopProxyFactory进行JDK 代理
AOP源码解析_第8张图片

AOP源码解析_第9张图片
返回装饰对象AOP对象
AOP源码解析_第10张图片

当aop调用数据的时候,使用创建一个调用链,进行调用
AOP源码解析_第11张图片

你可能感兴趣的:(源码,spring,aop,java,ioc)