SpringAOP
主要注解:
- @Aspect
- @Pointcut
- Advice
Point express:切面表达式
designators : 指示器:描述通过什么样的方式匹配想要的类的什么方法
- 匹配方法:使用通配符把执行的方法拦截下来 - execution() - //匹配任何以find开头而且只有一个Long参数的方法 @Pointcut("execution(* *..find*(Long))") public void argsDemo1(){}
- //匹配任何以find开头而且第一个参数为Long的方法 @Pointcut("execution(* *..find*(Long,..))") public void argsDemo3(){}
 
 
- 匹配注解:标注service类下面的所有的方法,在方法上面有指定注解的方法,方法里面有一个参数,是某一个类,而该类有指定注解,可以筛选 - @target(): - //匹配标注右Repository的类地下的方法,要求annotation的RetentionPolicy级别为RUNTIME @Pointcut("@target(org.springframework.stereotye.Repository)") public void annoTargetDemo(){}
 
- @args(): - //匹配传入的参数类标注右Repository注解的方法 @Pointcut("@args(org.springframework.stereotype.Repository)") public void annoArgsDemo(){}
 
- @within(): - //匹配标注右Beta的类底下的方法,要求的annotation的RetentionPolicy级别为CLASS @Pointcut("@within(com.google.common.annotations.Beta)") public void annoWithinDemo(){}
 
- @annotation(): - //匹配方法标注右AdminOnly的注解的方法 @Pointcut("@annotation(com.debuggg.demo.security.AdminOnly)") public void annoDemo(){}
 
 
- 匹配包/类型:匹配指定的包,类型及其子类 - within() - //匹配ProductService类里面的所有方法 @Pointcout("within(com.debuggg.service.ProductService)") public void matchType(){}
- //匹配com.debuggg包及其子包下所有类的方法 @Pointcut("within(com.debuggg..*)")
 
 
- 匹配对象:匹配指定对象,匹配spring托管的指定对象 - this() - //匹配AOP对象的目标对象为指定类型的方法,即DemoDao的aop代理对象的方法,其实就是实现该类的所有的方法 //即目标对象的代理对象 @Pointcut("this(com.debuggg.DemoDao)") public void thisDemo(){}
 
- bean() - //匹配所有以Service结尾的bean里面的方法 @Pointcut("bean(*Service)") public void beanDemo(){}
 
- target() - //匹配实现IDao接口的目标对象(而不是aop代理后的对象)的方法,这里即DemoDao的方法,其实就是实现该类的所有的方法 @Pointcut("target(com.debuggg.IDao)") public void targetDemo(){}
 
 
- 匹配参数:匹配方法的第一个参数是String类型的(例子) - args() - //匹配第一个参数为Long型的方法 @Pointcut("args(Long,..)") public void argsDemo4(){}
- //匹配任何只有一个Long参数的方法 @Pointcut("args(Long)") public void argsDemo2(){} //匹配任何只有一个Long参数的方法而且是在某个子包下面 @Pointcut("args(Long) && within(com.debuggg.service.*)") public void matchArgs(){}
 
 
wildcards 通配符
- *:匹配任意数量的字符
- ..:一般用于匹配任意数的子包或参数
- +:匹配指定类及其子类
operators 操作符(逻辑)
- &&:与
- || :或
- !:非
execution()表达式
格式:其中标注问号的表示可以省略
execution(
 modifier-pattern?:修饰符
 ret-type-pattern:返回值
 declaring-type-pattern:描述包名
 name-pattern(param-pattern):方法名(方法参数)
 throws-pattern? :匹配方法抛出的异常
)
例如:
//匹配public类型任意返回值,拦截了com.debuggg.service包下以Service结尾的类的任意方法,以及任意参数
@Pointcut("execution(public * com.debuggg.service.*Service.*(..))" )
//匹配public类型任意返回值,拦截了com.debuggg.service包以及子包下以Service结尾的类的任意方法,以及任意参数
@Pointcut("execution(public * com.debuggg.service..*Service.*(..))" )
//匹配public类型任意返回值,拦截了com.debuggg.service包以及子包下以Service结尾的类的任意方法,以及任意参数,以及抛出了IllegalAccessException异常的方法
@Pointcut("execution(public * com.debuggg.service..*Service.*(..)) throws java.lang.IllegalAccessException" )
public void matchType(){}
@Before("matchType()")
public void test(){}
5种Advice注解
- @Before,前置通知
- @After(finally),后置通知,方法执行完之后
- @AfterReturning,返回通知,成功执行之后
- @AfterThrowing,异常通知,抛出异常之后
- @Around,环绕通知
@Before:方法执行之前
    @Pointcut("@annotation(com.debuggg.apspecttest.AopAnnotationTest)")
    public void matchType(){}
    @Before("matchType()")
    public void before(){
        System.out.println();
        System.out.println("###before");
    }
After:方法执行之后
@After("matchType() && within(com.debuggg..*)")
public void afterDemo(){
    System.out.println("#################after aop by within");
}
@AfterReturning("matchType() && within(com.debuggg..*)")
public void afterReturning(){
    System.out.println("#################after aop by within");
}
@AfterThrowing("matchType() && within(com.debuggg..*)")
public void afterThrowing(){
    System.out.println("#################after aop by within");
}
@Around
    @Around("matchType() && within(com.debuggg..*)")
    public Object AfterThrowing(ProceedingJoinPoint pjp) throws Throwable{
        System.out.println("#############before");
        try{
            Object result = pjp.proceed(pjp.getArgs());
            System.out.println("###################return");
            return result;
        }catch (Throwable e){
            System.out.println("#################ex");
            throw e;
        }finally {
            System.out.println("##################after");
        }
    }
Advice中的参数及结果绑定
    @Before(value = "matchType() && within(com.debuggg..*) && args(userId)")
    public void before(JoinPoint joinPoint,Long userId){
        System.out.println("before ,args:" + userId);
    }
    @AfterReturning(value = "matchType() && within(com.debuggg..*)",returning = "returnValue")
    public void afterReturning(Object returnValue){
        if(returnValue != null){
            System.out.println("after return , result:" + returnValue)
        }
    }
AOP原理
动态代理:
JDK方式
参考:http://debuggg.com/article/209
cglib实现方式
被代理类的接口:
public interface Subject {
    void hello();
}
被代理类
public class RealSubject implements Subject {
    @Override
    public void hello() {
        System.out.println("hello");
    }
}
动态代理cglib类:
public class DemoMethodInterceptor implements MethodInterceptor {
    public Object getInstance(Object o){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(o.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("before in cglib");
        Object result = null;
        try {
            result = methodProxy.invokeSuper(o, objects);
            System.out.println("after return");
        }catch (Exception e){
            System.out.println("ex: " + e.getMessage());
            throw e;
        }finally {
            System.out.println("after in cglib");
        }
        return result;
    }
}
测试类:
public class Client {
    public static void main(String[] args) {
        // Enhancer enhancer = new Enhancer();
        // enhancer.setSuperclass(RealSubject.class);
        // enhancer.setCallback(new DemoMethodInterceptor());
        // Subject subject = (Subject) enhancer.create();
        Subject subject = (Subject) new DemoMethodInterceptor().getInstance(new RealSubject());
        subject.hello();
    }
}
探秘Spring AOP(下) http://debuggg.com/article/263
更多内容请访问:IT源点
注意:本文归作者所有,未经作者允许,不得转载
 
 
            