1.AOP术语
-
通知(advice):描述切面要完成的工作,并何时执行这个工作。
spring切面可以应用5种类型的通知:
- 前置通知(Before):在目标方法被调用之前调用通知功能。
- 后置通知(After):在目标方法完成之后调用通知,此时不会关心方法的输出是什么。
- 返回通知(After-returning):在目标方法成功执行之后调用通知。
- 异常通知(After-throwing):在目标方法抛出异常后调用通知;
- 环绕通知(Around):通知包裹了目标方法,在目标方法调用之前和之后执行自定义的行为。
-
连接点(joinpoint):在应用执行过程中能够插入切面的一个点。
-
切点(pointcut):切点定义了在何处使用切面。
-
切面(aspect):切面是通知和切点的结合,包括是什么、在何时、何处完成其工作。
-
引入(Introduction):向现有的类添加新方法或属性。通过引入,可以在无需修改现有类的情况下,让它们具有新的行为和状态。
-
织入(Weaving):织入是把切面应用到目标对象并创建新的代理对象的过程。在目标对象的生命周期中有多个点可以进行织入:
- 编译期:切面在目标类编译时被织入。这种方式需要特殊的编译器,如:AspectJ的织入编译器
- 类加载期:切面在目标类加载到JVM时被织入。这种方式需要特殊的类加载器,它可以在目标类被引入应用前增强其字节码,如:AspectJ 5的加载时织入(load-time weaving,LTW)
- 运行期:切面在应用运行的某个时刻被织入。一般情况下,在织入切面时,AOP容器会为目标对象动态创建一个代理对象,如SpringAOP.
2.Spring对AOP的支持
- Spring AOP基于动态代理构建,因此,Spring对AOP的支持局限于方法拦截。
- Spring在运行时通知对象
下面以演出和观众来演示Spring AOP的使用方式。
1、定义要使用切面的目标类:
package concert;
public interface Performance {
public void perform();
}
2、编写切点
使用切点表达式编写切点。下面展示了在perform()方法执行时触发通知的调用:
3、创建切面
可以通过注解和xml两种方式创建切面。 AspectJ提供了5个注解来定义通知:
| 注解 | 通知 |
|---|---|
| @Before | 通知方法在目标方法调用之前执行 |
| @After | 通知方法在目标方法返回或抛出异常后调用 |
| @AfterReturning | 通知方法在目标方法返回后调用 |
| @AfterThrowing | 通知方法在目标方法抛出异常后调用 |
| @Around | 通知方法会将目标方法封装起来 |
(1)注解 使用注解@Aspect表明该类是个切面。
package concert;
import ...;
@Aspect
public class Audience {
// @Pointcut注解定义一个可重用的切点。注解设置的值是个切点表达式。
@Pointcut("execution(** concert.Performance.perform(..))")
public void performance() {}
@Before("performance()")
public void takeSeats() {...}
// 也可以直接在注解后面写切点表达式
@AfterReturning("execution(** concert.Performance.perform(..))")
public void applause() {...}
@Around("performance()")
public void watchPerformance(ProceedingJoinPoint jp) {
System.out.println("do something before...");
// 调用被通知的方法
jp.proceed();
System.out.println("do something after.");
}
}
启动自动代理:只有启用了自动代理,才能解析切面相关的注解,并创建对应切面的代理 在配置类上使用@EnableAspectJAutoProxy启用自动代理功能:
@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class ConcertConfig {
@Bean
public Audience audience() {
return new Audience();
}
}
(2)xml 启动自动代理: 使用spring aop命名空间中的<aop:aspectj-autoproxy>元素启用自动代理功能:
<aop:aspectj-autoproxy />
3.引入
通过引入,可以为Spring bean添加新方法。