一. 说明
- Java Spring中使用AOP可以很方便的生成代理对象,从而添加自定义逻辑。
- 本文介绍如何调用代理对象的原始方法,而非代理后的方法
二. 原始类
@Component
public class AopTestClass {
public void method1() {
System.out.println("method1 execute");
}
}
三. 系统启动时生成代理对象
- proxyMethod:对指定方法添加前后逻辑,生成代理方法
- 代理对象根据原始对象是否有接口,使用JDK或CGLib动态代理
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AopTestClassProxy implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
return o;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (beanName.contains("aopTestClass")) {
return getProxy(bean, invocation -> this.proxyMethod(bean, invocation));
}
return bean;
}
private Object proxyMethod(Object bean, MethodInvocation invocation) throws Throwable {
String methodName = invocation.getMethod().getName();
if (methodName.equals("method1")) {
System.out.println("method1 before");
Object ret = invocation.proceed();
System.out.println("method1 after");
return ret;
}
Object ret = invocation.proceed();
return ret;
}
public static Object getProxy(Object obj, MethodInterceptor interceptor) {
ProxyFactory proxy = new ProxyFactory(obj);
proxy.setProxyTargetClass(true);
proxy.addAdvice(interceptor);
return proxy.getProxy();
}
}
四. 代理工具类
import lombok.SneakyThrows;
import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.aop.framework.AopProxy;
import org.springframework.aop.support.AopUtils;
import java.lang.reflect.Field;
public class AopUtil {
@SneakyThrows
public static Object getTarget(Object proxy) {
if (!AopUtils.isAopProxy(proxy)) {
return proxy;
}
if (AopUtils.isJdkDynamicProxy(proxy)) {
return getJdkDynamicProxyTargetObject(proxy);
} else {
return getCglibProxyTargetObject(proxy);
}
}
private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception {
Field h = proxy.getClass().getSuperclass().getDeclaredField("h");
h.setAccessible(true);
AopProxy aopProxy = (AopProxy) h.get(proxy);
Field advised = aopProxy.getClass().getDeclaredField("advised");
advised.setAccessible(true);
Object target = ((AdvisedSupport) advised.get(aopProxy)).getTargetSource().getTarget();
return target;
}
private static Object getCglibProxyTargetObject(Object proxy) throws Exception {
Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0");
h.setAccessible(true);
Object dynamicAdvisedInterceptor = h.get(proxy);
Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised");
advised.setAccessible(true);
Object target = ((AdvisedSupport) advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget();
return target;
}
}
五. 测试
@Autowired
private AopTestClass aopTestClass;
@Test
public void aopTest() {
System.out.println("执行代理方法");
aopTestClass.method1();
System.out.println();
System.out.println("执行原生方法");
AopTestClass result = (AopTestClass) AopUtil.getTarget(this.aopTestClass);
result.method1();
}