欢迎访问www.allbetgaming.com!

首页科技正文

吉安市人民政府网:spring——AOP原理及源码(一)

admin2020-10-2573

教程共分为五篇,从AOP实例的构建及其重要组件、基本运行流程、容器创建流程、关键方法调用、原理总结归纳等几个方面一步步走进AOP的世界。

本篇主要为读者演示构建AOP实例及AOP核心组件分析。

 

一、项目构建

读者可直接下载示例工程,或复制以下的代码到本地工程开启教程。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.tlj</groupId>
    <artifactId>spring-test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.3.13.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.13.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.inject/javax.inject -->
        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.44</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>4.3.12.RELEASE</version>
        </dependency>
    </dependencies>


</project>
pom.xml
package config;

import aop.LogAspects;
import aop.MathCalculator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@EnableAspectJAutoProxy
@Configuration
public class ConfigOfAOP {

    @Bean
    public MathCalculator calculator(){
        return new MathCalculator();
    }

    @Bean
    public LogAspects logAspects(){
        return new LogAspects();
    }
}
ConfigOfAOP 吉安市人民政府网:spring——AOP原理及源码(一) 第2张
package aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;

import java.util.Arrays;

/**
 * 切面类
 */
@Aspect
public class LogAspects {

    @Pointcut("execution(public int aop.MathCalculator.*(..))")
    public void poinCut(){}

    @Before("poinCut()")
    public void logStart(JoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        System.out.println(joinPoint.getSignature().getName()+" 运行。。。@Before "+ Arrays.asList(args));
    }

    @After("poinCut()")
    public void  logEnd(){
        System.out.println("除法结束..@After");
    }

    @AfterReturning(value = "poinCut()",returning = "result")//获取方法返回值
    public void logReturning(Object result){
        System.out.println("除法正常返回..@AfterReturning "+result);
    }

    @AfterThrowing(value = "poinCut()",throwing = "e")
    public void logException(Exception e){
        System.out.println("除法异常..@AfterThrowing "+e);
    }
}
LogAspects 吉安市人民政府网:spring——AOP原理及源码(一) 第2张
package aop;

public class MathCalculator {

    public int div(int i,int j){
        System.out.println("MathCalculator");
        return i/j;
    }
}
MathCalculator

项目目录结构如下:

吉安市人民政府网:spring——AOP原理及源码(一) 第6张

到这里,我们的项目是构建完了。

 

 

二、日志切面方法测试

打开测试类,运行测试方法

吉安市人民政府网:spring——AOP原理及源码(一) 第7张

 我们可以看到,总共打印了四行,除了第二行打印是业务方法的调用,其他都是调用日志切面类中的方法打印出来的。

这就是AOP的使用效果,除了用在日志,还有其他很多用法,这里就不赘述了。

 

 

三、关键组件探究

为什么AOP能在业务方法调用的前后和发生异常时调用切面方法呢,首先我们需要了解它引入了什么组件。

为了让AOP起作用,我们需要在配置类上添加@EnableAspectJAutoProxy注解,从字面上看,翻译为启动切面自动代理,那它是怎么启动的呢

ctrl+鼠标左键进入这个注解,我们可以看到EnableAspectJAutoProxy接口使用@Import注解导入了AspectJAutoProxyRegistrar这个类

吉安市人民政府网:spring——AOP原理及源码(一) 第8张

再次ctrl+鼠标左键进入AspectJAutoProxyRegistrar,可以看到,它实现了ImportBeanDefinitionRegistrar接口。

此接口中的registerBeanDefinitions方法,正是用来像容器中注册组件的。

看来想要知道@EnableAspectJAutoProxy注解到底给容器中添加了什么组件,我们需要进行调试,找到ImportBeanDefinitionRegistrar方法给容器中添加的组件。这个组件一定就是AOP实现的关键。

吉安市人民政府网:spring——AOP原理及源码(一) 第9张

 

 

 四、调试寻找组件

如下图,我们在ImportBeanDefinitionRegistrar接口的注册方法中打上断点。

 吉安市人民政府网:spring——AOP原理及源码(一) 第10张

点击debug开始调试,程序来到了AspectJAutoProxyRegistrar的registerBeanDefinitions方法

正在执行的是AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry),方法的字面意思:注册切面自动代理创造组件如果需要的话

 吉安市人民政府网:spring——AOP原理及源码(一) 第11张

接着进入这个方法直到以下这个方法,可以看到返回的是BeanDefinition类型,说明在方法里面有组件定义或注册相关的动作。

吉安市人民政府网:spring——AOP原理及源码(一) 第12张

 110行进行判断,如果容器中存在AUTO_PROXY_CREATOR_BEAN_NAME这个定义信息,进行以下判断,巴拉巴拉,最后return null,退出这个方法。

如果不存在,可以看到在125行已经有注册名为AUTO_PROXY_CREATOR_BEAN_NAME的组件的动作。

把鼠标放在AUTO_PROXY_CREATOR_BEAN_NAME上,可以看到它实际是叫internalAutoProxyCreator

吉安市人民政府网:spring——AOP原理及源码(一) 第13张

接着我们进行下一步,到110行时,显然第一次它是不存在这个类的,所以跳过if{}中的内容,到121行时,我们可以看看cls的信息,发现这个类叫AnnotationAwareAspectJAutoProxyCreator

吉安市人民政府网:spring——AOP原理及源码(一) 第14张

 

 到125行时,已经设置好AnnotationAwareAspectJAutoProxyCreator的各种属性,将其命名为internalAutoProxyCreator注册进容器,在126行进行返回。

在上面过程中,我们可以得到的结论是,@EnableAspectJAutoProxy注解实际上就是给容器中添加了名为internalAutoProxyCreator的组件,实际就是AnnotationAwareAspectJAutoProxyCreator这个类。

我们可以得出AnnotationAwareAspectJAutoProxyCreator就是实现AOP的核心组件。

接下来我们来探究一下AnnotationAwareAspectJAutoProxyCreator的继承关系,以及它是什么。

 

 

五、AnnotationAwareAspectJAutoProxyCreator组件是什么

进入这个类,发现它继承了AspectJAwareAdvisorAutoProxyCreator

 吉安市人民政府网:spring——AOP原理及源码(一) 第15张

那么AspectJAwareAdvisorAutoProxyCreator又是什么呢,接着进入AspectJAwareAdvisorAutoProxyCreator

发现AspectJAwareAdvisorAutoProxyCreator又继承了AbstractAdvisorAutoProxyCreator

吉安市人民政府网:spring——AOP原理及源码(一) 第16张

我们接着进入AbstractAdvisorAutoProxyCreator中查看

可以看到AbstractAdvisorAutoProxyCreator继承了AbstractAutoProxyCreator

吉安市人民政府网:spring——AOP原理及源码(一) 第17张

再进入AbstractAutoProxyCreator

可以看到AbstractAutoProxyCreator继承了ProxyProcessorSupport

并实现了SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware两个接口

吉安市人民政府网:spring——AOP原理及源码(一) 第18张

 

 接下来我们主要看这两个接口

SmartInstantiationAwareBeanPostProcessor明显是一个后置处理器接口,BeanFactoryAware是一个底层组件接口,实现BeanFactoryAware就可以注入并调用BeanFactory。

经过层层的进入,可以得到如下的关系

吉安市人民政府网:spring——AOP原理及源码(一) 第19张

这样看来,我们可以得出结论——AnnotationAwareAspectJAutoProxyCreator是一个后置处理器(后置处理器原理)

 

 

总结

  经过以上五个步骤,我们看到AOP的使用效果,发现了AOP的核心组件AnnotationAwareAspectJAutoProxyCreator是一个后置处理器,理清了AnnotationAwareAspectJAutoProxyCreator的继承实现关系。

总得来说,就是明白了核心组件是什么。

 

在接下来的篇章我们将从核心组件在哪发挥作用,何时发挥,以及做了什么,一步步深入原理。

,

诚信在线官网会员帐查询

诚信在线官网会员帐查询(原诚信在线官网)现已开放阳光在线手机版、阳光在线电脑客户端下载。阳光在线娱乐游戏公平、公开、公正,用实力赢取信誉。

转载声明:本站发布文章及版权归原作者所有,转载本站文章请注明文章来源!

本文链接:https://www.guangxianchuangan.com/post/562.html

网友评论

1条评论
  • 2020-10-25 00:00:47

    欧博亚洲客户端下载欢迎进入欧博亚洲客户端下载(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。这个很温暖的笔风

最新评论

  • Allbet开户 11/25 说:

    Allbetwww.aLLbetgame.us欢迎进入Allbet平台(Allbet Gaming):www.aLLbetgame.us,欧博平台开放欧博(Allbet)开户、欧博(Allbet)代理开户、欧博(Allbet)电脑客户端、欧博(Allbet)APP下载等业务。再发挥点才能

  • Allbet开户 11/25 说:

    Allbetwww.aLLbetgame.us欢迎进入Allbet平台(Allbet Gaming):www.aLLbetgame.us,欧博平台开放欧博(Allbet)开户、欧博(Allbet)代理开户、欧博(Allbet)电脑客户端、欧博(Allbet)APP下载等业务。再发挥点才能

  • Allbet代理 11/25 说:

    欧博官网欢迎进入欧博官网(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。真不错,很有深度

  • UG环球手机版下载 11/25 说:

    欧博代理欢迎进入欧博代理(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。码字辛苦了

  • 联博 11/24 说:

    欧博网址欢迎进入欧博网址(Allbet Gaming):www.aLLbetgame.us,欧博网址开放会员注册、代理开户、电脑客户端下载、苹果安卓下载等业务。谁加我呀

  • www.allbetgaming.com 11/24 说:

    欧博会员开户欢迎进入欧博会员开户(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。大爱!

  • allbet欧博真人客户端 11/24 说:

    欧博Allbet欢迎进入欧博Allbet官网(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。优秀啊,我自闭了

  • ALLBET官网娱乐平台开户 11/24 说:

    AllbetGmaing下载欢迎进入AllbetGmaing下载(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。我撂话,会大热大火哦!