分享

Spring2.X的 AOP支持

 碧海山城 2010-09-26

Spring2.X以后,有许多东西得到了改进,对AOP的实现和设置也提供了新增了两种方式:一种是基于XML Schema的设置;另一种是基于Annotation的支持。下面仅介绍注解的方式:

 

@Aspect

public class AdviceInterceptor {

    @Pointcut("execution (* com.bhsc.AOP.target.*.*(..))")     

// 声明一个切入点(第一个*后要留一个空格)

    private void anyMethod() {

    }

    @Before("anyMethod()")// 前置通知

    public void before() {

        System.out.println("前置通知");

    }  

    @AfterReturning("anyMethod()")//后置通知

    public void afterReturning(){

        System.out.println("后置通知");

    }

}

@Aspect表明这是一个切面,包括了通知和切入点,Pointcut注解用来声明一个切入点,括号中的参数是切入点的表达式,这里的表达式的意思是对com.bhsc.AOP.target包下的所有方法进行拦截。关于切入点表达式后面会有详细的说明。anyMethod是为切入点起一个名字,后面的“通知”都要依赖这个名字

 

<!-- 开启切面编程功能,搜索所有带有@Aspect注解的类,解析这个切面里的通知和切入点的定义 -->

<aop:aspectj-autoproxy />

<bean id="targetImple" class="com.bhsc.AOP.target.TargetImple" /> 

<bean id="theInterceptor"

        class="com.bhsc.aop2.AdviceInterceptor" />

ApplicationContext ctx = new

ClassPathXmlApplicationContext("aop2.xml");      

TargetInterface ti=(TargetInterface)

ctx.getBean("targetImple");

       

ti.hello("lisi");

ti.nihao("lisi");

 

前置通知

hello :lisi

后置通知

前置通知

你好 :lisi

后置通知

 

Pointcut表达式可以和Pointcut签名一起定义,这样,签名就可以给多个通知使用,比如前面的anyMethod,后面的通知都用到了它,@Before("anyMethod()")这里如果有多个签名还可以使用&&,||等对签名进行操作。另外,也可以在通知上直接定义Pointcut表达式,还可以带上JoinPoint参数,主要的目的是取得一些与JointPoint相关的信息,比如:

 

@Before("execution (* com.bhsc.AOP.target.*.*(..))")

public void before(JoinPoint joinPoint) {

        System.out.println("前置通知");

        System.out.println("目标对象:"+joinPoint.getTarget());

        System.out.println("参数:"+joinPoint.getArgs().toString());

        System.out.println("签名信息::"+joinPoint.getSignature());

}

 

目标对象:com.bhsc.AOP.target.TargetImple@176cad3

参数:[Ljava.lang.Object;@1fe1feb

签名信息:

org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint$MethodSignatureImpl@a084f8

 

其他通知

    @After("anyMethod()")// 最终通知

    public void after() {

        System.out.println("最终通知");

    }

   

    @AfterThrowing("anyMethod()")   // 例外通知

    public void AfterThrowing() {

        System.out.println("例外通知");

    }

 

    @Around("anyMethod()") //环绕通知

    public Object around(ProceedingJoinPoint pjp) throws Throwable {

        System.out.println("进入环绕");

        //if(){    // 进行一些判断,再执行环绕

        Object result = pjp.proceed();

        //}

        System.out.println("退出环绕");

        return result;

    }

匹配参数和返回值

1.参数

@Before("anyMethod() && args(in)")// 前置通知

    public void before(int in) {

        System.out.println("前置通知");

       

        System.out.println(in);

}  

 

在前置通知的方法中有一个参数,然后再把此参数作为拦截条件(即是说拦截带有一个String类型参数的方法)。args的名字和before方法参数名字相同

 

2.返回值,AfterReturn在有返回值的时候执行

@AfterReturning(pointcut ="anyMethod()",returning = "in")//后置通知

    public void afterReturning(JoinPoint joinPoint,int in){

//      System.out.println("目标对象:"+joinPoint.getTarget());

//      System.out.println("参数:"+joinPoint.getArgs().toString());

//      System.out.println("签名信息::"+joinPoint.getSignature());

//     

        System.out.println("后置通知返回结果:"+in);

    }

 

表达式切入点

1.格式:execution(返回值 空格 方法选择)。两部分组成,中间一定要有空格
返回值:可以是*,说明拦截任何方法。Java.lang.String(全名),拦截返回值为String类型的方法。 常用的实例如下:

方法选择:包名[类名].*()。设定要拦截的方法签名。

表达式(省略execution

说明

(java.lang.String 方法选择略)

拦截返回值为String类型的方法

(!void  方法选择略)

拦截返回值非空的方法

(* com.asm..*.*(..))

拦截com.asm包及子包下每个类的全部方法

(* com.asm.*.*(..))

拦截com.asm包下每个类的全部方法

(* com.asm.User.*(..))

拦截asm包下User类的所有方法

(* com.asm.User.*
(java.lang.String,..))

拦截User类中第一个参数为String,后面参数任一的方法

 

 

 

 

 

 

 

 

 

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多