方法一:使用@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();
}
}
运行结果与前面一样。