spring中的增强:注解和schema配置几种情况

来源:互联网 发布:土法炼钢 知乎 编辑:程序博客网 时间:2024/05/18 01:44

这里说一下spring的增强。先看schema的五种情况,如下代码:注意:
环绕增强的参数:ProceedingJoinPoint jp。ProceedingJoinPoint 是JoinPoint的子类。

public class MyAop {    public void before(JoinPoint jp){        System.out.println("before");        System.out.println("target:"+jp.getTarget());        System.out.println("args:"+Arrays.toString(jp.getArgs()));        System.out.println("kind:"+jp.getKind());    }    public void after(JoinPoint jp){        System.out.println("after");        System.out.println("target:"+jp.getTarget());        System.out.println("args:"+Arrays.toString(jp.getArgs()));        System.out.println("kind:"+jp.getKind());    }    public void afterRunning(JoinPoint jp,Object result){        System.out.println("afterRunning");        System.out.println("target:"+jp.getTarget());        System.out.println("args:"+Arrays.toString(jp.getArgs()));        System.out.println("kind:"+jp.getKind());        System.out.println("result:"+result);    }    public void afterThrowing(JoinPoint jp,RuntimeException e){        System.out.println("afterThrowing");        System.out.println("target:"+jp.getTarget());        System.out.println("args:"+Arrays.toString(jp.getArgs()));        System.out.println("kind:"+jp.getKind());        System.out.println("e:>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");        e.printStackTrace();    }    public void AroundInfo(ProceedingJoinPoint jp){        System.out.println("AroundInfo");        System.out.println("target:"+jp.getTarget());        System.out.println("args:"+Arrays.toString(jp.getArgs()));        System.out.println("kind:"+jp.getKind());        System.out.println(jp.getSignature());    }

再看看schema的配置。

<bean id="MyAop" class="aop.self.aop.MyAop"></bean><aop:config>        <aop:aspect ref="MyAop" >            <aop:pointcut expression="execution(* aop.self.biz.impl.*.add())" id="p1"/>            <aop:pointcut expression="execution(* aop.self.biz.impl.*.sub(..))" id="p2"/>            <aop:before method="before" pointcut-ref="p1"/>            <aop:after method="after" pointcut-ref="p2"/>            <aop:after-returning method="afterRunning" pointcut-ref="p1" returning="result"/>            <aop:after-throwing method="afterThrowing" pointcut-ref="p1" throwing="e"/>            <aop:around method="AroundInfo" pointcut-ref="p1" />        </aop:aspect>    </aop:config>

若方法换成实现接口写,如下。

public class MyAdvice implements MethodInterceptor {    //环绕增强    @Override    public Object invoke(MethodInvocation arg0) throws Throwable {        Object target=arg0.getThis();        Method method=arg0.getMethod();        Object [] args=arg0.getArguments();        System.out.println("环绕增强!");        System.out.println("调用"+target+"的"+method.getName()+"方法。方法入参:"+Arrays.toString(args));        try {            //前置通知            Object result = arg0.proceed();            System.out.println("调用" + target + "的" + method.getName() + "方法。方法返回值:" + result);            //返回通知,可以访问到方法的返回值            return result;        } catch (Throwable e) {            System.out.println("异常:" + e);            //访问方法的异常            throw e;        }    }//  @Override AfterReturningAdvice//  public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {//      // TODO Auto-generated method stub//      //  }    //MethodBeforeAdvice    //@Override//  public void before(Method method, Object[] args, Object target) throws Throwable {//      // TODO Auto-generated method stub//      //  }    //ThrowsAdvice//  public void afterThrowing(Method method, Object[] args, Object target, Exception ex){//      //      System.out.println(method.getName());   //  }}

这里说一下注解的写法。

@Order(2) //指定aop切面运行的优先级。@Aspect@Componentpublic class LoggerAspect {    /*     * 声明切入点表达式方法。     * 该方法一般不添加别的其他代码     */    @Pointcut("execution(public int *.*(..))")    public void declareJointExpression(){    }    //会写execution(public int com.ArithmeticCalculator.*(..))    @Before("declareJointExpression()")    public void  beforeMethod(JoinPoint jp){        String methodName=jp.getSignature().getName();        Object [] args=jp.getArgs();        System.out.println("the method "+methodName+"args:"+Arrays.toString(args));        System.out.println("wwwwwwwww");        }    @After("execution(public int *.*(..))")    public void  afterMethod(JoinPoint jp){        String methodName=jp.getSignature().getName();        Object [] args=jp.getArgs();        System.out.println("the method "+methodName+"args:"+Arrays.toString(args));        System.out.println("after");        }    @AfterReturning(value="execution(public int *.*(..))",returning="result")    public void  afterReturning(JoinPoint jp,Object result){        String methodName=jp.getSignature().getName();        Object [] args=jp.getArgs();        System.out.println("the method "+methodName+"args:"+Arrays.toString(args)+"result:"+result);        System.out.println("wwwwwwwww");        }    /*     * 方法出现异常时会执行的代码     */    @AfterThrowing(value="execution(public int *.*(..))",throwing="e")    //这里Exception 可以换成其他异常进行捕捉    public void  afterThrowing(JoinPoint jp,Exception e){        String methodName=jp.getSignature().getName();        Object [] args=jp.getArgs();        System.out.println("the method "+methodName+"args:"+Arrays.toString(args)+"exception:"+e);        System.out.println("wwwwwwwww");        }    /*     * 类似于动态代理 过程     * 参数:ProceedingJoinPoint     * 有返回值,返回值为目标方法的返回值     */    @Around("execution(public int *.*(..))")    public Object  aroundMethod(ProceedingJoinPoint jp){        String methodName=jp.getSignature().getName();        Object [] args=jp.getArgs();        System.out.println("wwwwwwwww");            Object result=null;        try {            //前置通知            System.out.println("the method "+methodName+"args:"+Arrays.toString(args));            result=jp.proceed();            //返回通知            System.out.println("the method ends with"+result);        } catch (Throwable e) {            //异常通知            System.out.println("the method "+methodName+"occurs exception:"+e);            e.printStackTrace();        }        //后置        System.out.println("end with>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");        return result;    }}

增加一个关于优先级的验证。记得用@order

@Order(1)@Aspect@Componentpublic class ValidationAspect {    //不在同一个包下面记得写包名com.LoggerAspect.declareJointExpression()    @Before("LoggerAspect.declareJointExpression()")    public void validateArgs(JoinPoint jp){        System.out.println("validator:"+Arrays.deepToString(jp.getArgs()));    }}

这样写了之后只需在xml中加入两行配置就好

<context:component-scan base-package="com"></context:component-scan>    <aop:aspectj-autoproxy/>

还有spring4及以上使用注解时,记得导入jar包。
aspectjweaver-x.x.jar

0 0
原创粉丝点击