JDK、CGLIB、Spring 三种实现代理的区别(三)Spring的ProxyFactory
2023-09-27 14:27:23 时间
转: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()); } }
运行结果分别为:
相关文章
- jdk、jre、spring、java ee、java se
- Spring Boot Intellij 运行应用的时候 Command line is too long. Shorten command line for 错误
- Spring Boot 2.0(七):Spring Boot 如何解决项目启动时初始化资源
- Spring的两种代理JDK和CGLIB的区别浅谈
- 如何手动获取 Spring 容器中的 bean?
- Spring @Value使用详解
- 【SSH进阶之路】Spring的IOC逐层深入——Spring的IOC原理[通俗解释一下](三)
- Spring Boot【快速入门】
- Spring学习总结(二)——静态代理、JDK与CGLIB动态代理、AOP+IoC
- Spring的两种动态代理:Jdk和Cglib 的区别和实现
- MongoDB系列三(Spring集成方案).
- Spring Boot 学习17--改变JDK编译版本
- Spring Boot 使用 Groovy 模板引擎开发视图层
- Spring Boot 系列:最新版优雅停机详解
- JDK和Spring中的设计模式
- Spring Boot 打包方式的选择
- spring成神之路第十三篇:使用继承简化bean配置(abstract & parent)
- Spring Cloud中服务的发现与消费