1.基本概念的理解
连接点:程序执行过程中,能够插入到切面的点。通过这些点,切面代码加入到正常流程中。体现一种时机性,什么时候该做什么。
通知(增强):更多体现在什么时候。体现一种标志性。
切点:更多体现一种切入性。通过这个点,知道要做的事是什么。也是通过这个点,将之前之后要做的事与这件事分开。
2.简单demo
@Aspect
public class Audience {
@Pointcut("execution(* concern.Performance.performance(..))")
public void perform() {
}
@Before("perform()")
public void silenceCellPhones() {
}
@Before("perform()")
public void takeSeats() {
}
@AfterReturning("perform()")
public void applause() {
}
@AfterThrowing("perform()")
public void demandRefund() {
}
}
环绕通知:(感觉没卵用。。。)
@Around("execution(* concern.Performance.perform(..))")
public void around(ProceedingJoinPoint) {
// ......
pjp.proceed();
// ......
}
3.代理切面类
第一种:配置类的方式
@Configuration
@ComponentScan
@EnableAspectJAutoProxy
public class ConcernConfig {
@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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<context:component-scan base-package="concern"/>
<aop:aspectj-autoproxy/>
<bean class="concern.Performance" id="performance"/>
</beans>
4.切面表达式中参数的使用
public class TrackCounter {
private Map<Integer, Integer> trackCounts = new HashMap<>();
@Pointcut("execution(* concern.Performance.perform(int)) && args(trackNumber))")
public void trackPlayed(int trackNumber) {
}
@Before("trackPlayed(trackNumber)")
public void countTrack(int trackNumber) {
int currentCount = getPlayCount(trackNumber);
trackCounts.put(trackNumber, currentCount + 1);
}
public int getPlayCount(int trackNumber) {
return trackCounts.containsKey(trackNumber) ? trackCounts.get(trackNumber) : 0;
}
}
5.@DeclareParents的使用
参见:https://blog.csdn.net/u010502101/article/details/76944753
6.xml配置aop
<aop:config>
<aop:aspect ref="">
<aop:pointcut id="" expression="execution(* concern.Perform.performance(int)) and args(trackNumber)"/>
<aop:before ref-pointcut="" method=""/>
<aop:after-throwing ref-pointcut="" method=""/>
<aop:after-returning ref-pointcut="" method=""/>
</aop:aspect>
</aop:config>
<aop:config>
<aop:aspect ref="">
<aop:pointcut id="" expression="execution(* concern.Perform.performance(int)) and args(trackNumber)"/>
<aop:around pointcut-ref="" method="">
</aop:aspect>
</aop:config>
7.xml配置实现新功能
<aop:declare-parents types-matching="concert.Performance+" implement-interface="concert.Encoreable" default-impl="concert.DefaultEncoreable"/>
<aop:declare-parents implement-interface="concert.Encoreable" types-matching="concert.Performance+" delegate-ref="defaultEncoreable"/>
<bean id="defaultEncoreable" class="concert.DefaultEncoreable"/>
上下两种方式。default-impl一个是直接使用,另一个是引用bean。