二刷AOP源码(上)

简介: 二刷AOP源码(上)

他做每一件小事都像救命稻草一样紧紧抓住,等到有一天我一看,嚯,好家伙,他抱住的已经是可以让我仰望的参天大树了            <士兵突击>

1.静态代理与JDK动态代理与CGLB动态代理2.AOP体系2.1 基础概念的理解2.2 Spring提供操作组件2.2.1.提建议2.2.2.寻找建议者2.2.3.代理的创建时机2.2.4.代理的创建2.2.5.代理的执行3.总结


有一天:领导建议我们给删除操作方法添加操作日志。

为了完成这个意愿,AOP为此做了多少工作呢??

这一切的一切,都要从代理说起


1.静态代理与JDK动态代理与CGLB动态代理


1.静态代理:

  • 硬编码静态代理: 说白了就是通过编码上的设计达到代理的效果。
  • AspectJ编译织入 :编译期把内容编译到字节码中,

重点:编译期把内容织入代理对象

2.动态代理:通过动态生成新的类字节码,来达到动态代理的目标

  • JDK动态代理:Proxy+InvocationHandler 模式
  • CGLB动态代理: Enhancer + MethodInterceptor(CallBack)

重点:生成了新的字节码,动态代理

具体可阅读我的静态代理与JDK动态代理与CGLIB动态代理


2.AOP体系


2.1 基础概念的理解

再来重温这句话领导建议给删除操作方法添加操作日志

这里面包含的点:

  • 谁提的:领导
  • 给谁提的:删除操作
  • 提的什么建议:添加操作日志

至此引出了三个接口出来:

  • Advisor: 提建议者
  • Pointcut:切点,给哪一类人提建议
  • Advise:建议,通知(建议的内容)

当然这里面还有几个隐藏的角色,AOP体系也有对应的定义:

  • TargetSource: 目标对象
  • Joinpoint :连接点,当领导提到建议具体到某个方法上时,Joinpoint就是那个方法的信息封装体。在Joinpoint中我们可以获取到目标方法的相关信息
  • Advised:当一个人被建议成功后,他就可以看做一个Advised

他们之间的关系:

  • Advisor= Pointcut + Advise
  • Advised = N * Advisor :一个人可能被多个 建议者建议。

这几个概念就组成了AOP体系的整体概念框架。

此时:我们达成一个共识,

  • 当我在做AOP编程的时候,其实就是一个提建议的过程。
  • 当给目标对象提了有效建议会为其创建代理


2.2 Spring提供操作组件

有了规范的指导,剩下的就是实现规范,Spring提供了哪些东西呢?

以我们最熟悉的切面编程为例,事务,来看看AOP体系的运作过程.


2.2.1.提建议

切面,事务本质都是提建议。例如下面,我给cn.wqd.aop包下的方法提了日志记录的建议,事务是给方法提了事务控制的建议


(1.切面

@Aspect
@Component
public class WebLogAcpect {
    private Logger logger = LoggerFactory.getLogger(WebLogAcpect.class);
    //定义切入点,切入点为com.example.aop下的所有函数
    @Pointcut("execution(public * cn.wqd.aop..*.*(..))")
    public void webLog(){}
    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        System.out.println("这里是AOP前置方法");
    }
}


(2.事务

Service
public class TransactionalService {
    @Autowired
    DataSource dataSource;
    @Autowired
    UserDao userDao;
    @Transactional
    public String save(){
        System.out.println("被事务方法");
        User user = new User("被事务方法",1);
        Map<Object, Object> map = TransactionSynchronizationManager.getResourceMap();
        System.out.println(userDao.getClass().getName());//
        userDao.save(user);
        return "save";
    }

如何使用AOP是我们最熟悉的,但是他们又和上面的角色有啥关系呢?别急往下看


2.2.2.寻找建议者

提了建议,Spring如何知道是否有提建议者。


(1.BeanFactoryAdvisorRetrievalHelper

为了把应用中的那些建议者找出来,Spring首先提供了一个BeanFactoryAdvisorRetrievalHelper,建议者检索工具:目的是识别出那些实现了Advisor接口的的建议者,并把他们注册成一个Bean,并缓存起来。

public class BeanFactoryAdvisorRetrievalHelper {
public List<Advisor> findAdvisorBeans() {
  (1)
  advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                    this.beanFactory, Advisor.class, true, false);
  (2)
  this.cachedAdvisorBeanNames = advisorNames;
  (3)
  advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
}

检索逻辑:找到所有实现了Advisor的Beandefiniton;缓存他们的beanName;调用Bean创建逻辑,创建一个Bean出来。

直接实现Advisor接口,显示的表明自己就是一个建议者。

但是平时我们开发并不是用这种直接实现Advisor的方式。@Aspect注解,事务才是我们常用的。那他们到底是不是建议者呢?


(2.@Aspect切面建议者

BeanFactoryAspectJAdvisorsBuilder

@Aspect注解的类的建议读取出来,Spring为此提供了一个建议者构建工具BeanFactoryAspectJAdvisorsBuilder

Aspect建议者构建器。

从其名字直译:他是一个专门构建Aspect建议者的Bean的工具


private final AspectJAdvisorFactory advisorFactory;
public BeanFactoryAspectJAdvisorsBuilder(ListableBeanFactory beanFactory) {
        this(beanFactory, new ReflectiveAspectJAdvisorFactory(beanFactory));
}


通过其构造方法,我们发现他默认会创建一个ReflectiveAspectJAdvisorFactory,从其名字可以看出,他是通过反射的机制来工作的。BeanFactoryAspectJAdvisorsBuilder的大部分工作其实就是由ReflectiveAspectJAdvisorFactory完成的。


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
2月前
|
Java 数据库连接 应用服务中间件
Spring5源码(39)-Aop事物管理简介及编程式事物实现
Spring5源码(39)-Aop事物管理简介及编程式事物实现
24 0
|
2月前
Spring5源码(31)-基于@AspectJ的AOP
Spring5源码(31)-基于@AspectJ的AOP
21 0
|
2月前
|
Java Spring
Spring5源码(30)-基于Schema的AOP
Spring5源码(30)-基于Schema的AOP
19 0
|
2月前
|
Java Spring
Spring5源码(28)-Aop知识点回顾以及基于Advice接口的增强实现
Spring5源码(28)-Aop知识点回顾以及基于Advice接口的增强实现
30 0
|
4月前
|
Java Spring
【Spring源码】Spring中的AOP底层原理分析
【Spring源码】Spring中的AOP底层原理分析
|
8月前
|
Java Spring
|
8月前
|
Java Android开发 Spring
|
8月前
|
存储 缓存 Dubbo
|
9月前
|
XML 开发框架 Java
《Spring6核心源码解析》已完结,涵盖IOC容器、AOP切面、AOT预编译、SpringMVC,面试杠杠的!
全网首个全面解析Spring6核心源码的专栏,涵盖:IOC容器、AOP切面、声明式事务、AOT预编译和SpringMVC,让你从根本上彻底掌握Spring6核心技术。
315 1
《Spring6核心源码解析》已完结,涵盖IOC容器、AOP切面、AOT预编译、SpringMVC,面试杠杠的!
|
9月前
|
XML 存储 缓存
(六)Spring源码解析:Spring AOP源码解析
(六)Spring源码解析:Spring AOP源码解析
108 0