JDK、CGLIB、Spring 三种实现代理的区别(三)Spring的ProxyFactory
转:https://blog.csdn.net/sunnycoco05/article/details/78901449
之前两篇文章中我们说到了JDK proxy和CGLIB实现动态代理的方式,这回说说Spring的方式。Spring中代理对象可通过xml配置方式获得,也可通过ProxyFactory手动编程方式创建对象。我们主要讲手动编程的方式。Spring中的代理对象其实是JDK Proxy和CGLIB Proxy 的结合。
下面我们使用ProxyFactory的方式创建代理对象,顺便看看和JDK的proxy以及CGLIB中的proxy联系。
还是使用前两节中的例子。创建需要代理的类(MyTarget)、接口(PeopleService)及其实现(EnglishService),分别看看对接口和类的代理:
public class MyTarget { public void printName() { System.err.println("name:Target-"); } }
public interface PeopleService { public void sayHello(); public void printName(String name); }
public class EnglishService implements PeopleService { @Override public void sayHello() { System.err.println("Hi~"); } @Override public void printName(String name) { System.err.println("Your name:" + name); } }
下面创建一个MethodInterceptor实现方法调用的前后拦截,这里的拦截只是进行简单的打印信息。
这里需要用到额外的包 aopalliance.jar和aspectjweaver。(这里的MethodInterceptor 对比cglib)
import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class AroundInteceptor implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { System.err.println(invocation.getMethod().getName() + "调用之前"); Object res = invocation.proceed(); System.err.println(invocation.getMethod().getName() + "调用之后"); return res; } }
使用Spring aop包中的ProxyFactory创建代理,并通过addAdvice
增加一个环绕方式的拦截:
package com.spring; import org.springframework.aop.framework.ProxyFactory; import org.testng.annotations.Test; import com.cglib.MyTarget; import com.proxy.api.PeopleService; import com.proxy.impl.EnglishService; import com.spring.aop.AroundInteceptor; public class ProxyFactoryTest { @Test public void classProxy() { //代理对象未指定接口,使用CGLIB生成代理类 ProxyFactory factory = new ProxyFactory(); factory.setTarget(new MyTarget()); factory.addAdvice(new AroundInteceptor()); MyTarget targetProxy = (MyTarget) factory.getProxy(); targetProxy.printName(); System.err.println(targetProxy.getClass().getName()); } @Test public void interfaceProxy() { //代理对象指定接口PeopleService,目标类为实现PeopleService的EnglishService,使用JDK proxy生成代理类 ProxyFactory factory = new ProxyFactory(); factory.setInterfaces(new Class[] { PeopleService.class }); factory.addAdvice(new AroundInteceptor()); factory.setTarget(new EnglishService()); PeopleService peopleProxy = (PeopleService) factory.getProxy(); peopleProxy.sayHello(); System.err.println(peopleProxy.getClass().getName()); } }
运行结果分别为: