@Aspect
Spring使用AspectJ来申明通知方法。
注解 | 通知 |
---|---|
@After | 通知方法会在目标返回或抛出异常时调用 |
@AfterReturning | 通知方法会在目标返回后调用 |
@AfterThrowing | 通知方法在目标抛出异常时调用 |
@Around | 通知方法将目标方法封装起来 |
@Before | 通知方法在目标方调用前执行 |
@Pointcut
可以通过@Pointcut注解申明频繁使用的切点表达式
@EnableAspectJAutoProxy
启动AspectJ自动代理
如果使用xml,需要使用Spring命名空间中国的<aop: aspectj-autoproxy>。
示例
Performance 接口
public interface Performance {
void perform(String performContent);
}
表演实现类
@Component
public class Concert implements Performance {
@Override
public void perform(String performContent) {
System.out.println(performContent + "表演中。。。");
}
}
定义切面(@Pointcut + @Before + @Around + args)
args:处理通知中的参数。
@Aspect
public class Audience {
@Pointcut("execution(* com.zachary.aop.Performance.perform(String)) && args(performContent)")
public void performance(String performContent) {};
@Before("performance(performContent)")
public void silenceCellPhones(String performContent) {
System.out.println(performContent + "Sliencing cell phones");
}
@Around("performance(performContent)")
public void watchPerformance(ProceedingJoinPoint jp, String performContent) {
try {
System.out.println(performContent);
System.out.println("Taking seats");
jp.proceed();
System.out.println("CLAP CLAP CLAP!!!");
} catch (Throwable e) {
System.out.println("Demand a refund");
e.printStackTrace();
}
}
}
JavaConfig配置
@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class ConcertConfig {
@Bean
public Audience audience() {
return new Audience();
}
}
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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.zachary.aop"/>
<aop:aspectj-autoproxy />
</beans>
注意:xml中不需要,如果添加了会生成两个切面。执行时会执行两遍。
测试
@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration(classes = ConcertConfig.class)
@ContextConfiguration(locations = "classpath:aop-config.xml")
public class ConcertConfigTest {
@Autowired
private Performance concert;
@Test
public void test() {
concert.perform();
}
}
执行调用方法初始化Spring上下文:
通过JavaConfig配置初始化
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ConcertConfig .class);
Person person = (Person) ctx.getBean("concert");
通过xml配置初始化
AbstractApplicationContext context = new FileSystemXmlApplicationContext("classpath:aop-config.xml");
Performance concert = (Performance) context.getBean("concert");