相关文章推荐
淡定的菠萝  ·  元对象机制·  4 月前    · 
淡定的菠萝  ·  Django: ...·  4 月前    · 
淡定的菠萝  ·  ICU4J Android 框架 ...·  8 月前    · 
淡定的菠萝  ·  Cocos2d-x: HttpClient ...·  8 月前    · 
淡定的菠萝  ·  python json去掉反斜杠 ...·  9 月前    · 
淡定的菠萝  ·  Laravel Email ...·  10 月前    · 
俊秀的手套  ·  Qt | 显示网络图片 ...·  1小时前    · 
失恋的青椒  ·  20.5 OpenSSL ...·  1小时前    · 
爱旅游的帽子  ·  20.1 OpenSSL ...·  1小时前    · 
爱健身的跑步鞋  ·  机电产品进口管理办法·  2 小时前    · 
飘逸的马克杯  ·  【GIT SourceTree】_<git ...·  2 小时前    · 
博学的豌豆  ·  Team Foundation ...·  2 小时前    · 
  • 编译期织入,在编译的时候将增强的代码加入到代理对象里,需要特殊的编译器
  • 加载期织入(load-time weaving),在类加载的时候将增强的代码加入到代理对象里,需要使用 -javaagent 参数指定 agent 用于修改类的字节码
  • 运行期织入,在运行期将增强的代码加入到代理对象里
  • 在 spring 中, AOP 默认是使用运行期织入,通过 CGLIB 或 JDK 实现代理,此外也可以用 aspectj 实现加载期织入

    使用 load-time weaving

    在 spring 使用 load-time weaving 有两种情况。一种是 spring 的内置功能,例如 Caching 和 Async,一种是用户用 @Aspect 或 aop.xml 定义的切面

    spring 的内置功能

    这种情况需要将 AdviceMode 设置为 ASPECTJ,再将 javaagent 设置为 aspectjweaver.jar

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    public class AsyncApp {
    public static void main(String[] args) {
    ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
    HelloService hello = ctx.getBean("helloService", HelloService.class);
    hello.hello();
    }

    @Configuration
    @EnableAsync(mode = AdviceMode.ASPECTJ) // 使用 aspectj 增强
    static class Config {
    @Bean
    public HelloService helloService() {
    return new HelloService();
    }

    @Bean
    public ConcurrentTaskExecutor executor() {
    return new ConcurrentTaskExecutor();
    }
    }
    }

    public class HelloService {
    @Async
    public void hello() {
    System.out.println("hello");
    }
    }
    1
    java -javaagent:aspectjweaver-1.9.4.jar -jar myapp.jar

    使用 @Aspect 的情况

    这种情况可以将 javaagent 设置为 aspectjweaver.jar , 也可以设置为 spring-instrument.jar,如果设置为 spring-instrument.jar 就需要有 @EnableLoadTimeWeaving

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    public class AspectjApp {
    public static void main(String[] args) {
    ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
    HelloService hello = ctx.getBean("helloService", HelloService.class);
    hello.hello();
    }

    @Configuration
    @EnableAspectJAutoProxy
    @EnableLoadTimeWeaving // 打开 load-time weaving 功能
    static class Config {
    @Bean
    public HelloService helloService() {
    return new HelloService();
    }

    @Bean
    public Interceptor myInterceptor() {
    return new Interceptor();
    }
    }
    }

    public class HelloService {
    public void hello() {
    System.out.println("hello");
    }
    }

    @Aspect
    public class Interceptor {
    @Pointcut("execution(* HelloService.hello(..))")
    public void PointCut() {}

    @Before("PointCut()")
    public void before() {
    System.out.println("before");
    }
    }

    这种情况需要有 aop.xml, 即使内容为空

    1
    2
    3
    4
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
    <aspectj>
    </aspectj>
    1
    java -javaagent:spring-instrument-5.1.9.RELEASE.jar -jar myapp.jar

    如果两种情况都需要使用,则可以设置两个 javaagent

    1
    java -javaagent:aspectjweaver-1.9.4.jar -javaagent:spring-instrument-5.1.9.RELEASE.jar -jar myapp.jar
     
    推荐文章