实现AOP

方法一:使用@Aspect注解

由于Spring只支持XML式而没有实现注解式(也叫AspectJ式)的AOP,所以,要使用@Aspect 注解,只能引入AspectJ相关依赖包 ,也就是:aspectjrt.jar 与 aspectjweaver.jar。

package chapter4;

import org.aspectj.lang.annotation.*;

@Aspect
public class Audience {
    @Pointcut("execution(* chapter4.Musician.perform(..))")  //如果Musician是某个接口(A)的实现,使用的时候应直接使用接口类型,即A a;a.perform();
    public void performance(){}

    @Before("performance()")
    public void silenceCellPhone()
    {
        System.out.println("手机静音");
    }
    @Before("performance()")
    public void takeSeats()
    {
        System.out.println("坐下");
    }

    @AfterReturning("performance()")
    public void applause()
    {
        System.out.println("鼓掌");
    }

    @AfterThrowing("performance()")
    public void fail()
    {
        System.out.println("失败");
    }
}
package chapter4;

import org.springframework.stereotype.Component;

@Component
public class Musician{
    public void perform() {
        System.out.println("音乐家表演了");
    }
}
 
package chapter4;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.junit.Assert.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = chapter4Config.class)
public class Chapter4Test {

    @Autowired
    Musician musician;

    @Test
    public void test()
    {
        musician.perform();
    }
}
运行结果
 
手机静音
坐下
音乐家表演了
鼓掌
创建环绕通知

将Audience代码改为以下,其他不变。

package chapter4;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
@Aspect
public class Audience {
    @Pointcut("execution(* chapter4.Musician.perform(..))")
    public void performance(){}
    @Around("performance()")
    public void watchPerformance(ProceedingJoinPoint jp) {
        try {
            System.out.println("手机静音");
            System.out.println("坐下");
            jp.proceed();
            System.out.println("鼓掌");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            System.out.println("失败");
        }
    }
}

        运行程序后可以看到,这个通知所达到的效果与之前的前置通知与后置通知是一样的。但是,现在他们位于同一个方法之中,不像之前那样分散在四个不同的通知方法里。

        

方法二:使用xml


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

        <!--启用Aspect自动代理-->
        <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

        <bean id="musician" class="chapter4.Musician"></bean>
        <bean id="audience" class="chapter4.Audience"></bean>

        <aop:config>
                <aop:aspect ref="audience">
                        <aop:pointcut id="perform" expression="execution(* chapter4.Musician.perform(..))"/>
                        <aop:before pointcut-ref="perform" method="silenceCellPhone" />
                        <aop:before pointcut-ref="perform" method="takeSeats" />
                        <aop:after pointcut-ref="perform" method="applause"/>
                </aop:aspect>
        </aop:config>
</beans>
package chapter4;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

public class Audience {
    
    public void silenceCellPhone()
    {
        System.out.println("手机静音");
    }
    
    public void takeSeats()
    {
        System.out.println("坐下");
    }

    public void applause()
    {
        System.out.println("鼓掌");
    }

    @AfterThrowing("performance()")
    public void fail()
    {
        System.out.println("失败");
    }

}
package chapter4;

import org.springframework.context.annotation.*;

@Configuration
@ImportResource("classpath:chapter4.xml") //注入xml资源
@ComponentScan
public class chapter4Config {

    @Bean
    public Audience audience()
    {
        return new Audience();
    }
}

运行结果与前面一样。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值