这里说一下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
@Component
public 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
@Component
public 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