【Spring实战】第4章 面向切面的Spring
POM 依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.0.7.RELEASE</version>
</dependency>
<!-- Spring AOP 依赖 AspectJ,不然会报 ReflectionWorldException-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.2</version>
</dependency>
使用注解配置 AOP
我的代码
开启 AOP
使用 @EnableAspectJAutoProxy
开启 AOP
@Configuration
@EnableAspectJAutoProxy // 启用自动代理
@ComponentScan
public class AopConfig {}
方式一:调用目标对象的方法,被代理类拦截
使用 @Aspect
定义切面
@Component
@Aspect // 注意:pom.xml 中 aspectjweaver 的 scope 为 runtime 的话,该注解会报红
public class Audience {
/*
切点表达式:
* aop.Performance.perform(..)
返回任意类型 全限定类名.方法名(任意参数列表)
*/
@Pointcut("execution(* aop.Performance.perform(..))")
public void performance() {
}
// 指定接收的参数
@Pointcut("execution(* aop.Performance.playTrack(int)) && args(number)")
public void trackPlayed(int number) {
}
@Before("performance()")
public void silenceCellPhone() {
System.out.println("Before");
}
@Around("trackPlayed(int)")
public void watchPerformance(ProceedingJoinPoint jp) {
try {
System.out.println("Around start");
jp.proceed(); // 被代理的实际方法
jp.proceed(new Object[]{2}); // 替换传入的参数为 2
System.out.println("Around end");
} catch (Throwable ignored) {
}
}
}
方式二:代理暴露新接口,底层没有实现这些接口
@Component
@Aspect
public class EncoreableIntroducer {
@DeclareParents(value = "aop.Performance+", defaultImpl = DefaultEncoreable.class)
public static Encoreable encoreable;
}
测试类
RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AopConfig.class)
public class AopTest {
@Autowired
private Performance performance;
@Test
public void test1() {
performance.perform();
// 引用新功能,即使类没有实现这个接口
Encoreable encoreable = (Encoreable) this.performance;
encoreable.performEncore();
}
@Test
public void test2() {
performance.playTrack(1);
}
}