AspectJ
@AspectJ的风格类似纯Java注解的普通Java类
Spring可以使用AspectJ来做切入点解析
AOP的运行时依旧是纯的Spring AOP 对AspectJ的编译器或者织入无依赖性
Spring中配置@AspectJ
Spring的AOP可以通过对@AspectJ注解的支持和在XML中配置来实现,本文通过实例简述如何在Spring中使用AspectJ.
确保AspectJ的aspectjweaver.jar库包含在应用程序(版本1.6.8或者更高)的classpath中
注解:
@Configuration
@EeableAspectJAutoProxy
public class AppConfig{
}
XML配置文件:
<aop:aspectj-autoproxy />
@AspectJ切面使用@Aspect注解配置,拥有@Aspect的任何bean将被Spring自动识别并应用
用@Aspect注解的类可以有方法和字段,他们也可能包括切入点(pointcut),通知(Advice)和引入(introduction)声明
@Aspect注解是不能通过类路径自动检测发现的,所以需要配合使用@Component注解或者在xml配置bean
例子:如下base-package="com.imooc.aop.aspectj"中无法检测到@Aspect注解
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans 7 http://www.springframework.org/schema/beans/spring-beans-4.1.xsd 8 http://www.springframework.org/schema/context 9 http://www.springframework.org/schema/context/spring-context-4.1.xsd 10 http://www.springframework.org/schema/aop 11 http://www.springframework.org/schema/aop/spring-aop-4.1.xsd"> 12 13 <context:component-scan base-package="com.imooc.aop.aspectj"/> 14 <aop:aspectj-autoproxy> </aop:aspectj-autoproxy> 15 </beans>
一个类中的@Aspect注解表示它为一个切面,并且将自己从自动代理中排除:如果切面类和业务类在同一个包下,会将自己从自动代理中排除
<bean id="myAspect" class="com.aop.schema.MyAspect">
<!--configure properties of aspect here as normal-->
</bean>
package org.xyz;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class NotVeryUserfulAspect{
}
pointcut:
一个切入点通过一个普通的方法定义来提供,并且切入点表达式使用@Pointcut注解,方法返回类型必须为void
定义一个名为‘nayOldTransfer‘,这个切入点将匹配任何名为"transfer"的方法的执行
@Pointcut("execution(* transfer(..))")//the pointcut pxpression
private void anOldTransfer(){}//the pointcut signature
AOP支持的AspectJ切入点指示符如下:Supported Pointcut Designators
execution:用于匹配方法执行的连接点;
within:用于匹配指定类型内的方法执行;
this:用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配;
target:用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配;
args:用于匹配当前执行的方法传入的参数为指定类型的执行方法;
@target:用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解;
@args:用于匹配当前执行的方法传入的参数持有指定注解的执行;
@within:用于匹配所以持有指定注解类型内的方法;
@annotation:用于匹配当前执行方法持有指定注解的方法;
例子:
1 package com.imooc.aop.aspectj; 2 import org.aspectj.lang.annotation.Aspect; 3 import org.aspectj.lang.annotation.Pointcut; 4 import org.springframework.stereotype.Component; 5 @Component 6 @Aspect 7 public class MoocAspect { 8 9 @Pointcut("execution(* com.imooc.aop.aspectj.biz.*Biz.*(..))") 10 public void pointcut() {} 11 12 @Pointcut("within(com.imooc.aop.aspectj.biz.*)") 13 public void bizPointcut() {} 14 }
-------------------
组合pointcut:根据具体情况使用单个或者组合,一般不建议特别复杂
切入点表达式可以通过 且(&&)、或(||)、非(!)来进行组合,也可以通过名字引用切入点表达式。
通过组合,可以建立更加复杂的切入点表达式
1 @Pointcut("execution(public * (..))") 2 private void anyPublicOperation() {} 3 @Pointcut("within(com.xyz.someapp.trading..)") 4 private void inTrading() {} 5 @Pointcut("anyPublicOperation() && inTrading()") 6 private void tradingOperation() {}
-----------------------------------
定义良好的pointcuts:
·AspectJ是编译期的AOP
·检查代码并匹配连接点与切入点的太假是昂贵的
·一个号的切入点应该包括以下几点:
-选择特定类型的连接点,如:execution,get,set,call,handler
-确定连接点范围,如:witnin,withincode
-匹配上下文信息,如:this,target,@annotation
-----------------------------------
一:使用AspectJ注解:
1,启用对AspectJ的支持:
通过在Spring的配置中引入下列元素来启用Spring对AspectJ的支持:
<aop:aspectj-autoproxy />
或者(如果不是使用XSD的话)
<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />
2,声明一个带有@Aspect注解的类,在这个类中声明那些方法需要被‘关注‘(利用@Pointcut),在那些时机点进行关注(利用@Before,@AfterReturning等等...),执行‘切入‘的方法
3,在Spring的配置文件中定义这个‘切面‘类:任意带有一个@Aspect切面(拥有@Aspect注解)的bean都将被Spring自动识别并用于配置在Spring AOP.
4,使用被Spring管理的bean,在执行被‘关注‘的方法时,‘切入‘的方法就会被执行.
一个完整的例子:
需要被‘切入‘的类: