- 基于 JDK 实现动态代理
- 基于 Cglib 实现动态代理
- 基于 Spring 的 ProxyFactory 实现动态代理
- ProxyFactory 的实现源码分析
JDK 动态代理的原理是利用反射机制,在运行时创建代理类,必要条件是代理对象基于接口实现。
创建一个接口及其实现类。
public interface IService { void sayHello(); }
public class JdkServiceImpl implements IService { @Override public void sayHello() { System.out.println("Hello JAVA Proxy"); } }
创建代理处理类,必须实现 InvocationHandler 接口。
@AllArgsConstructor public class ServiceInvocationHandler implements InvocationHandler { private final Object target; @Override public Object invoke(Object obj, Method method, Object[] args) throws Throwable { System.out.println("-------- begin ----------"); Object result = method.invoke(target, args); System.out.println("-------- end ----------"); return result; } }
执行动态代理
public class JdkProxyTest { public static void main(String[] args) { IService service = new JdkServiceImpl(); ServiceInvocationHandler handler = new ServiceInvocationHandler(service); IService proxy = (IService) Proxy.newProxyInstance(JdkProxyTest.class.getClassLoader(), new Class[]{IService.class}, handler); proxy.sayHello(); System.out.println(); System.out.println(proxy.getClass().getSimpleName() + " extend " + proxy.getClass().getSuperclass().getSimpleName() + " implements " + Arrays.stream(proxy.getClass().getInterfaces()) .map(Class::getSimpleName) .collect(Collectors.joining(","))); } }
输出结果如下,可以看出在 sayHello 方法前后,执行了代理处理类中的代码输出,说明通过 JDK 动态代理实现了代理增强。
-------- begin ---------- Hello JAVA Proxy -------- end ---------- $Proxy0 extend Proxy implements IService
最后一行的输出显示了动态生成的代理类的继承关系,该类实现代理对象的接口,JDK 动态代理的继承机制决定了只能对接口进行代理。
基于 Cglib 实现动态代理Cglib 动态代理的原理是利用字节码技术,在运行时创建一个继承代理类的 class,所以代理对象不需要实现接口,但要求被代理类及方法必须不是 final 的
创建一个需要被代理的类
public class CglibServiceImpl { public void sayHello() { System.out.println("Hello Cglib Proxy"); } }
创建方法拦截器,必须实现 MethodInterceptor 接口,实现代理增强
public class ServiceInterceptor implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] params, MethodProxy methodProxy) throws Throwable { System.out.println("-------- begin ----------"); Object result = methodProxy.invokeSuper(obj, params); System.out.println("-------- end ----------"); return result; } }
执行代理 *** 作
public class CglibProxyTest { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(CglibServiceImpl.class); enhancer.setCallback(new ServiceInterceptor()); CglibServiceImpl proxy = (CglibServiceImpl) enhancer.create(); proxy.sayHello(); System.out.println(); System.out.println(proxy.getClass().getSimpleName() + " extend " + proxy.getClass().getSuperclass().getSimpleName() + " implements " + Arrays.stream(proxy.getClass().getInterfaces()) .map(Class::getSimpleName) .collect(Collectors.joining(","))); } }
输出结果如下
-------- begin ---------- Hello Cglib Proxy -------- end ---------- ServiceImpl$$EnhancerByCGLIB$$ef25c05 extend ServiceImpl implements Factory基于 Spring 的 ProxyFactory 实现动态代理
Spring 也提供了自己动态代理实现,但其实做的还是整合的工作,底层依然是基于上文中的两种技术。
创建方法拦截器,需要实现 MethodInterceptor 接口(这个接口在 org.aopalliance.intercept 包中,与 cglib 中的不是同一个)。
public class AopInterceptor implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("-------- begin ----------"); Object result = invocation.proceed(); System.out.println("-------- end ----------"); return result; } }
执行代理 *** 作
public class SpringProxyTest { public static void main(String[] args) { executeJdkProxy(); // executeCglibProxy(); } public static void executeJdkProxy() { ProxyFactory factory = new ProxyFactory(); factory.setInterfaces(IService.class); factory.setTarget(new JdkServiceImpl()); factory.addAdvice(new AopInteceptor()); IService proxy = (IService) factory.getProxy(); proxy.sayHello(); printClassName(proxy); } public static void executeCglibProxy() { ProxyFactory factory1 = new ProxyFactory(); factory1.setTarget(new CglibServiceImpl()); factory1.addAdvice(new AopInteceptor()); CglibServiceImpl proxy1 = (CglibServiceImpl) factory1.getProxy(); proxy1.sayHello(); printClassName(proxy1); } public static void printClassName(Object proxy) { System.out.println(); System.out.println(proxy.getClass().getSimpleName() + " extend " + proxy.getClass().getSuperclass().getSimpleName() + " implements " + Arrays.stream(proxy.getClass().getInterfaces()) .map(Class::getSimpleName) .collect(Collectors.joining(","))); } }
执行 executeJdkProxy 方法输出
-------- begin ---------- Hello World -------- end ---------- $Proxy18 extend Proxy implements IService,SpringProxy,Advised,DecoratingProxy
执行 executeCglibProxy 方法输出
-------- begin ---------- Hello Cglib Proxy -------- end ---------- CglibServiceImpl$$EnhancerBySpringCGLIB$b39275 extend CglibServiceImpl implements SpringProxy,Advised,Factory
通过最后输出的类继承结构可以看出在 ProxyFactory 之下的实现原理,executeJdkProxy 与 executeCglibProxy 方法不同的一点是调用 factory.setInterfaces 设置了接口,如果不设置接口,那么底层还是使用 cglib 实现,虽然最终呈现出来的效果是一样的。所以具体使用哪种方案实现,并不处决了代理对象是不是接口,而是有没有向 ProxyFactory 设置接口(当然设置接口的前提首先得实现接口)。
ProxyFactory 的实现源码分析根据方法 getProxy 进行源码跟踪
public class ProxyFactory extends ProxyCreatorSupport { public Object getProxy() { return createAopProxy().getProxy(); } }
createAopProxy 方法在其父类中实现,调用 AopProxyFactory.createAopProxy 方法创建一个 AopProxy 对象,AopProxyFactory 默认使用 DefaultAopProxyFactory。
public class ProxyCreatorSupport extends AdvisedSupport { private AopProxyFactory aopProxyFactory; public ProxyCreatorSupport() { this.aopProxyFactory = new DefaultAopProxyFactory(); } protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } return getAopProxyFactory().createAopProxy(this); } }
在 DefaultAopProxyFactory 的 createAopProxy 方法,可以看到根据不同的条件会选择创建不同的 AopProxy。
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable { @Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } } }
AopProxy 的实现类分别代表不同的实现策略
以 JdkDynamicAopProxy 的实现为例,可以看到最终调用的还是 JDK 提供的 Proxy.newProxyInstance() 方法创建代理对象。
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable { public Object getProxy() { return getProxy(ClassUtils.getDefaultClassLoader()); } public Object getProxy(@Nullable ClassLoader classLoader) { if (logger.isTraceEnabled()) { logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource()); } Class>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true); findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)