AOP的基本概念
Spring面向切面编程,Spring事AOP的一种实现,AspectJ是另一种流行的AOP实现;
首先牢记关于AOP的相关概念
Spring提供了4种类型的AOP支持:
- 基于代理的经典Spring AOP(没有看过,不懂)
- 纯POJO切面(这个需要XML配置的支持,因为POJO只是提供了满足切点条件时所要调用的方法,这就是声明式地将对象转换为切面的简便方式)
- @AspectJ注解驱动的切面
- 注入式AspectJ切面(适用于Spring各版本)
前三种都是Spring AOP实现的变体,Spring AOP构建在动态代理基础上,因此Spring对AOP的支持局限于方法的拦截(其实我们实际使用的更多的也是方法的拦截,所以没有影响)。
(AOP:面向切面编程,首先需要知道切面是什么,切面是通知和切点的结合,那么通知和切点又是什么,这里主要使用@AspectJ注解的方式说明,下面讲详细的,如果发现错误欢迎补充,谢谢~)
- 通知(Advice):通知就是定义切面什么时候以及做什么事情
eg:
@Before(execution(** apackage.bclass.cmethod(..)))
如上面的示例,使用通知来说明切面需要在什么时候做什么
因为通知定了切面什么时候,那么通知有五种类型
1)前置通知 -注解使用@Before,在方法前调用
2)后置通知-注解使用@After,在方法后调用
3)正确返回通知-注解使用@AfterReturning,在方法正确返回结果后调用
4)异常通知-注解使用@AfterThrowing,在方法抛异常时进行调用
5)环绕通知-注解使用@Around,在方法调用前后进行调用
- 切点(PointCut):切点说明切面是在什么地方插入
切点,我们熟知的就是切点表达式,但是Spring中只满足一部分的AspectJ的指示器,在这里记录一下(最常用的是execution)
AspectJ指示器 | 描述 |
---|---|
arg | 限制连接点匹配参数为指定类型的执行方法 |
@args() | 限制连接点匹配参数由指定注解标识的执行方法 |
this() | 限制连接点指定AOP代理的bean引用为指定类型的类 |
target | 限制连接点匹配目标对象为指定类型的类 |
@target() | 限制连接点匹配特定的执行对象,这些对象对应的类要具有指定类型的注解 |
within() | 限制连接点匹配指定的类型 |
@within() | 限制连接点匹配指定注解所标注的类型(当使用Spring AOP时,方法定义在由指定的注解所注视的类里) |
@annotation | 限定匹配带有指定注解的连接点 |
eg:
execution(** apackage.bclass.cmethod(..))
- 切面:了解完通知和切点,就了解了切面,因为切面是通知和切点的结合,完整的定义类是什么时候、什么地方、做什么
eg:
//@Aspect注解标明该类是一个切面
@Aspect
public class MsgAspect {
//可以在切面内使用 @PointCut定义一个可以重用的切点
@Pointcut("execution(**com.wy.crud.send(..))")
public void pointCut(){}
//以下是三种通知,分别是前置、后置、异常
@Before("pointCut()")
public void beforSend(){
System.out.println("连接邮箱地址");
}
@After("pointCut()")
public void afterSend() {
System.out.println("返回结果");
}
@AfterThrowing("pointCut()")
public void throwSend() {
System.out.println("返回失败");
}
}
- 连接点(JoinPoint):是指在应用过程中能够插入切面的一个点。这个点可以是调用方法时、抛出异常时、甚至可以时修改一个字段时。切面代码就可以利用这些点插入到应用的正常流程之中,并添加新的行为。
- 引入(Introduction):引入允许我们向现有的类添加新的方法或者属性。
- 织入(weaving):织入是把切面应用到目标对象并创建新的代理对象的过程。切面在指定的连接点被织入到目标对象中。在目标对象的生命周期中有多个点可以i进行织入:
1)编译期:切面在目标类编译时被织入。这种方式需要特殊的编译器,AspectJ的织入编译器就是以这种方式织入切面的;
2)类加载期:切面在目标类加载到JVM时被织入。这种方式需要特殊的类加载器,可以在目标类被引入应用之前增强该目标类的字节码;
3)运行期:切面在应用运行过程的某个时刻被织入。一般情况下,在织入切面时,AOP容器会为目标对象动态地创建一个代理对象。SpringAOP就是以这种方式织入切面的。
AOP的使用
上面在讲解概念的时候说明了基本使用,现在我们已经有一个切面类了,但是如果要将切面类加载到Spring应用程序上下文并且说明要开启面向切面编程,才可以使用
可以使用JavaConfig配置开发自动代理(面向切面编程)
@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class AspectConfig() {
@Bean
public MsgAspect msgAspect(){
return new MsgAspect();
}
}