不一样的视角来学习Spring源码之AOP---上

2022-05-10 16:13:44 浏览数 (1)

不一样的视角来学习Spring源码之AOP---上

AOP

AOP 底层实现方式之一是代理,由代理结合通知和目标,提供增强功能

除此以外,aspectj 提供了两种另外的 AOP 底层实现:

  • 第一种是通过 ajc 编译器在编译 class 类文件时,就把通知的增强功能,织入到目标类的字节码中
  • 第二种是通过 agent 在加载目标类时,修改目标类的字节码,织入增强功能
  • 作为对比,之前学习的代理是运行时生成新的字节码

简单比较的话:

  • aspectj 在编译和加载时,修改目标字节码,性能较高
  • aspectj 因为不用代理,能突破一些技术上的限制,例如对构造、对静态方法、对 final 也能增强
  • 但 aspectj 侵入性较强,且需要学习新的 aspectj 特有语法,因此没有广泛流行

AOP 实现之 ajc 编译器

准备一个待增强的MyService类

代码语言:javascript复制
@Service
public class MyService {

    private static final Logger log = LoggerFactory.getLogger(MyService.class);

    public static void foo() {
        log.debug("foo()");
    }
}

准备一个切面类:

代码语言:javascript复制
@Component
@Aspect 
public class MyAspect {

    private static final Logger log = LoggerFactory.getLogger(MyAspect.class);

    @Before("execution(* com.aop01.service.MyService.foo())")
    public void before() {
        log.debug("before()");
    }
}

引入aspectJ的编译插件acj编译器

代码语言:javascript复制
    <build>
        <plugins>
            <!-- 编译期织入 -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.14.0</version>
                <configuration>
                    <complianceLevel>1.8</complianceLevel>
                    <source>1.8</source>
                    <target>1.8</target>
                    <showWeaveInfo>true</showWeaveInfo>
                    <verbose>true</verbose>
                    <Xlint>ignore</Xlint>
                    <encoding>UTF-8</encoding>
                </configuration>
                <executions>
                    <execution>
                        <configuration>
                            <skip>false</skip>
                        </configuration>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

运行程序,查看被acj编译器动态织入后的class文件:

AspectJ官网 更多AspectJ的内容可以参考本篇文章进行学习


0 人点赞