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
    评论
Spring AOP是Spring框架中的一个重要模块,它提供了一种面向切面编程的方式,可以让开发者将一些通用的、横切的关注点(如事务、安全、缓存等)从业务逻辑中剥离出来,使得业务逻辑更加清晰简洁,代码复用更加方便。 Spring AOP的实现原理主要基于Java动态代理和CGLIB动态代理两种方式,其中Java动态代理主要用于接口代理,而CGLIB动态代理则主要用于类代理。Spring AOP中的核心概念是切面(Aspect)、连接点(Join Point)、通知(Advice)、切点(Pointcut)和织入(Weaving)。 在Spring AOP中,切面是一个横向的关注点,它跨越多个对象和方法,通常包含一些通用的功能,如日志记录、安全控制等。连接点则是程序中可以被切面拦截的特定点,如方法调用、异常抛出等。通知是切面在连接点执行前后所执行的动作,包括前置通知(Before)、后置通知(After)、异常通知(AfterThrowing)、返回通知(AfterReturning)和环绕通知(Around)。切点则是用来匹配连接点的规则,它可以指定哪些连接点会被切面拦截。织入则是将切面应用到目标对象中的过程,它可以在编译时、类加载时、运行时等不同的阶段进行。 Spring AOP解析涉及到很多细节,包括代理的生成、通知的执行、切点的匹配等,需要深入了解Spring框架的内部实现和Java的反射机制。对于初学者而言,可以先从Spring AOP的基本概念和用法入手,了解其实现原理的同时,也可以通过调试和查看码来加深理解。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值