【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);
    }
}
posted @ 2023-05-11 19:13  seolas  阅读(13)  评论(0编辑  收藏  举报