- 通过aspectJ给MyService添加增强方法,需要添加插件。使用aspectj-maven-plugin进行编译,而不是使用javac进行编译。
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.14.0</version>
<configuration>
<complianceLevel>1.8</complianceLevel>
<source>8</source>
<target>8</target>
<showWeaveInfo>true</showWeaveInfo>
<verbose>true</verbose>
<Xlint>ignore</Xlint>
<encoding>UTF-8</encoding>
</configuration>
<executions>
<execution>
<goals>
<!-- use this goal to weave all your main classes -->
<goal>compile</goal>
<!-- use this goal to weave all your test classes -->
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
- MyService为被增强的类
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@Service
public class MyService {
private static final Logger log = LoggerFactory.getLogger(MyService.class);
public static void foo() {
log.debug("foo()");
}
}
- 实现切面
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Aspect // ⬅️注意此切面并未被 Spring 管理
public class MyAspect {
private static final Logger log = LoggerFactory.getLogger(MyAspect.class);
@Before("execution(* com.itheima.service.MyService.foo())")
public void before() {
log.debug("before()");
}
}
- 调用MyService方法
@SpringBootApplication
public class A09 {
private static final Logger log = LoggerFactory.getLogger(A09.class);
public static void main(String[] args) {
// ConfigurableApplicationContext context = SpringApplication.run(A10Application.class, args);
// MyService service = context.getBean(MyService.class);
//
// log.debug("service class: {}", service.getClass());
// service.foo();
//
// context.close();
new MyService().foo();
/*
学到了什么
1. aop 的原理并非代理一种, 编译器也能玩出花样
*/
}
}
- 执行结果
在target目录下查看反编译得到的类文件
@Service
public class MyService {
private static final Logger log = LoggerFactory.getLogger(MyService.class);
public MyService() {
}
public static void foo() {
MyAspect.aspectOf().before();
log.debug("foo()");
}
}
发现foo内部加入了切面方法,实现了增强。
因为MyAspect并没有添加@Component注解,所以MyAspect并没有被Srpring管理。
上述代码实际上是使用aspectJ来实现增强,而且增强的是静态方法。
总结:
aspectJ增强的相较于代理增强优点:
代理增强是通过重写方法来实现的,不能增强静态方法。而aspectJ可以增强静态方法。