前置增强、后置增强、环绕增强听起来说实话,我完全不清楚是什么意思,研究以后,发现很简单,就是对方法的增强,比如前置增强,就是我有一个方法A,但是有一些功能是通用的,我不想写到A里面,但是A方法又需要使用,这个时候就可以使用前置增强,这样每次在执行方法A之前,就会自动调用这个增强方法了。
1、增强分类
- 前置增强:org.springframework.aop.BeforeAdvice 代表前置增强,因为spring只支持方法级的增强,所以MethodBeforeAdvice 是目前可用前置增强,表示在目标方法执行前实施增强。
- 后置增强 :org.springframework.aop.AfterAdvice 代表后增强,表示目标方法在执行后实施增强
- 环绕增强 :org.springframework.aop.MethodInterceptor 代表环绕增强,表示目标方法执行前后实施增强
- 异常抛出增强 :org.springframework.aop.ThrowsAdvice 代表抛出异常增强,表示目标方法抛出异常后实施增强
- 引介增强 :org.springframework.aop.IntroductionInterceptor 代表引介增强,表示在目标类中添加一些新的方法和属性
2 实例
1、先写一个需要被增强的方法
这里写的是A类下面的aaaa()方法,下面将对这个方法增强
package com.bootdo.clouddocommon.advice;
public class A {
public void aaaa() {
System.out.println("方法执行了~");
}
}
2、前置增强类
package com.bootdo.clouddocommon.advice;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.stereotype.Component;
/**
* 前置增强
*
* @author Administrator
*
*/
@Component
public class HelloBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.err.println("--------------before return----------------------------");
System.err.println(method);
System.err.println(args);
System.err.println(target);
System.err.println("--------------before return----------------------------");
}
}
3、后置增强类
package com.bootdo.clouddocommon.advice;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.stereotype.Component;
/**
* 后置增强
*
* @author Administrator
*
*/
@Component
public class HelloAfterAdvice implements AfterReturningAdvice {
@Override
public void afterReturning(Object obj, Method method, Object[] args, Object target) throws Throwable {
System.err.println("--------------after return----------------------------");
System.err.println(obj);
System.err.println(method);
System.err.println(args);
System.err.println(target);
System.err.println("--------------after return----------------------------");
}
}
4、环绕增强类
package com.bootdo.clouddocommon.advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.stereotype.Component;
@Component
public class HelloAroundAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
before();
Object result = invocation.proceed();
after();
System.out.println("arround");
return result;
}
private void after() {
System.out.println("after");
}
private void before() {
System.out.println("before");
}
}
5、对方法aaaa进行增强并测试类
package com.bootdo.clouddocommon.advice;
import org.springframework.aop.framework.ProxyFactory;
public class Client {
public static void main(String[] args) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(new A());
// 1.分别 添加前置增强 、后置增强
proxyFactory.addAdvice(new HelloBeforeAdvice());
proxyFactory.addAdvice(new HelloAfterAdvice());
// 3.环绕增强
proxyFactory.addAdvice(new HelloAroundAdvice());
// 2.同时 实现前置增强、后置增强
// proxyFactory.addAdvice(new HelloBeforeAfterAdvice());
// proxyFactory.addAdvice(new HelloAroundAdvice());
// proxyFactory.addAdvice(new HelloThrowAdvice());
A a = (A) proxyFactory.getProxy();
a.aaaa();
}
}
proxyFactory.addAdvice 将增强类 放到代理类中,然后调用即可实现
以下是执行结果截图:
异常抛出增强和引介增强同理
总结:以上代码看起来还是挺简单的,但个人觉得还是没有直接切入方便,但这种方法也有这种方式的好处吧,就跟自定义注解一样,有些地方需要用到,有些地方不需要用到,需要用的地方就增强,不需要用的地方就不增强。
此文章是基于demo写的,感兴趣的可以下载运行看看。
下载地址:https://download.csdn.net/download/qq_28483283/11233595
前端是vue写的,后端是springboot+springcloud
ps:本来不想要设置下载积分的,可是csdn强制要5积分,我也很无奈.