Aop 源码解读

2020-08-04 22:40:13 浏览数 (1)

动态Aop的使用

  1. 创建用于拦截的bean
代码语言:javascript复制
public class TestBean{
    
    private String testStr = "testStr";
    
    public String getTestStr(){
        return testStr;
    }
    
    public void setTestStr(String testStr){
        this.testStr = testStr;
    }
    
    public void test(){
        System.out.println("test");
    }
}
  1. 创建 Advisor

spring 使用 @AspectJ 注解对POJO进行标注,在所有的test方法执行前在控制台打印beforeTest

代码语言:javascript复制
@Aspect
public class AspectJTest {
    
    @Pointcut("execution(* *.test(...))")
    public void test(){
        
    }
    
    @Before("test()")
    public void beforeTest(){
        System.out.println("beforeTest");
    }
    
    @After("test()")
    public void afterTest(){
        System.out.println("afterTest")
    }
    
    @Around("test()")
    public Object aroundTest(ProceedingJoinPoint p){
        System.out.println("before");
        Object o = null;
        try{
            o = p.proceed();
        }catch(){
            
        }
        System.out.println("after");
        return o;
    }
}
  1. 创建配置文件
代码语言:javascript复制
<?xml version=” 1. encoding UTF 。〉
<beans xmlns=” http . //www . Springframework . org/schema/bean s ” 
xmlns : xsi=” http : //www . w3 org/2001/XMLSchema - instance ” 
xmlns aop http //www Springframework rg/schema/aop
xmlns · context=” http : //wwwSpringfr amework . org/schema/context ” 
xsi :schemaLocation="http : //www . Spri ngframework . org/schema/beans 
http : //wwwSpringframework . org/schema/beans/Spring- beans- 3 . 0 . xsd 
http : //www . Springframework . org/schema/aop 
http : //www . Springframework rg/schema/aop/Spring aop xsd
http : //www . Springframework . org/schema/ context 
http //www Springframework org/schema/c ntext/Spring context- 3 . 0 . xsd 
” >
<aop · aspect] - autoproxy /> 
<bean id=” test ” class=” test.TestBean ” /> 
<bean class= ”test.AspectJTes t ” />
</beans>

创建Aop代理

实际上 AnnotationAwareAspectJAotuProxyCreator 实现了 BeanPostProcessor 接口, 而实现 BeanPostProcessor 后,当spring加载这个Bean会在实例化前调用postProcess-AfterInitialization方法

  • 获取增强器
  1. 获取所有的beanName , 所有beanFactory中注册的bean都会被提取出来
  2. 遍历beanName,找出AspectJ注解的类,进一步处理
  3. 对标记为AspectJ的注解进行增强器的提取.
  4. 将提取结果加入缓存

对获取增强器步骤的细分:

  1. 切点信息的获取,获得方法上的注解,将注解封装到类
  2. 根据切点信息生成增强,不同的增强所体现的逻辑是不同的@Before("test()"),@After("test()"),根据不同的注解类型封装不同的增强器
  • 创建代理
  1. 获取当前类中的属性
  2. 添加代理接口
  3. 封装Advisor并加入到ProxyFactory中
  4. 设置要代理的类

静态Aop使用

加载时植入(Load-Time Weaving, LTW)是在虚拟机载入字节码文件时动态植入AspectJ切面. Spring 框架的值添加为 AspectJ LTW 在动态植入提供了更细粒度的控制.spring 的LTW可以让每一个类加载器打开LTW,更加细粒度

  1. spring 配置文件进行修改
代码语言:javascript复制
<?xml versio 1. 0 ” encoding= ” UTF 8 ” ?>
<beans xmlns = ” http : llwww Springframework . orglschemalbeans ” 
- 3 . 0 . xsd 
xml ns : xsi= ” http : llwww . w3 orgl200llXMLSchema - instance " 
xml ns : aop= ” http llwww . Springframework . orglschemalaop” 
xmln s : context= ” http : llwww . Springfra mework . orglschema/context ” 
xsi :schemaLocation= ” h ttp : l/www . Spri ngframework . org/schema/beans 
http llwww Springframework orglschema/beans/Spr ng beans 
http //www . Springframework . org/schema/aop 
http //www Springframework org/sch臼旧/aop/Spring aop - 3 . 0 .xsd 
http : //www . Springframework . org/schema/context http : //www . 
Spr ngframework org/schema/conte t/Spring coηtext xsd
” ><aop : aspectj - autoproxy /> 
<bea id tes t ” class=” test TestBean ” />
<bean class= ” test . AspectJTest ” />
// 加入这句话
 <context.load-time-weaver /> 
</beans> 

2.加入Aop.xml 在class目录下META-INF下

代码语言:javascript复制
<!DOCTYPE aspect] PUBLIC ” //AspectJ//DTD//EN””http : //www . eclipse . org/aspectj/dtd/
aspectj . dtd” > 
<aspectj> 
<weaver> 
< 1-- only weave classes in our application- specific packages --> 
<include within=” test . * ” />
</weaver> 
<aspects> 
<' - - weave in ] ust this aspect --> 
<aspect name=” test . AspectJTest " /> 
</aspects> 
</aspectj> 

主要是告诉AspectJ对哪一个包进行植入,使用那些增强器

3.加入启动参数

代码语言:javascript复制
-javaagent: path/to/Spring-agent.jar

0 人点赞