专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

Java中的动态代理

Java中的动态代理

说起动态代理,首先想到的就是Spring,在Spring中有两种动态代理方式:JDK动态代理和Cglib动态代理。

JDK动态代理

JDK动态代理是Java本来就有的一种代理方式,关键类是java.lang.reflect.InvocationHandler

我们先创建一个简单的SpringBoot项目,然后创建UserServiceUserServiceImpl

public interface UserService {
    void add();
}

 @Service public class UserServiceImpl implements UserService { @Override public void add() { System.out.println("添加用户..."); } } 

这个UserServiceImpl就是我们要代理的类,它继承了UserService接口,所以使用JDK动态代理。

然后我们创建一个简单的类来模拟事务处理

@Component
public class TransactionManager {

    public void begin() {
        System.out.println("创建事务");
 } public void commit() { System.out.println("提交事务"); } public void rollback() { System.out.println("回滚事务"); } } 

代理器

最后要创建代理器了,首先要实现java.lang.reflect.InvocationHandler这个接口,复写invoke方法。

@Component
public class JdkProxyHandler implements InvocationHandler {

    /**
 * 事务处理器 */ @Resource private TransactionManager transcationManager; @Setter private Object target; @Override public Object invoke(Object proxy, Method method, Object[] args) { Object ret = null; try { //模拟事务开始 transcationManager.begin(); ret = method.invoke(target, args); //模拟事务提交 transcationManager.commit(); } catch (Exception e) { //模拟事务回滚 transcationManager.rollback(); e.printStackTrace(); } return ret; } public <T> T getProxy() { return (T) Proxy.newProxyInstance( //类加载器 this.getClass().getClassLoader(), //为哪些接口做代理 target.getClass().getInterfaces(), //增强对象 this); } } 

测试

首先我们把代理器和要代理的对象注入进来,通过jdkProxyHandler.getProxy方法得到代理对象。

@SpringBootTest
class Springdemo1ApplicationTests {

    @Resource
    private JdkProxyHandler jdkProxyHandler;
 @Resource private UserService userService; @Test public void testJdkProxy() throws Exception { //设置要代理的对象 jdkProxyHandler.setTarget(userService); //得到代理对象 UserService proxy = jdkProxyHandler.getProxy(); //代理对象执行方法 proxy.add(); } } 

执行结果:

89_1.png

Cglib动态代理

我们也要实现一个接口InvocationHandler,不过这个接口是Spring提供的org.springframework.cglib.proxy.InvocationHandler。复写其中的invoke方法。 获取代理类的方式不一样,使用org.springframework.cglib.proxy.Enhancer#create()这个方法获取。

@Component
public class CglibProxyHandler implements InvocationHandler {

    /**
 * 事务处器 */ @Resource private TransactionManager transcationManager; @Setter private Object target; @Override public Object invoke(Object proxy, Method method, Object[] args) { Object ret = null; try { //模拟事务开始 transcationManager.begin(); ret = method.invoke(target, args); //模拟事务提交 transcationManager.commit(); } catch (Exception e) { //模拟事务回滚 transcationManager.rollback(); e.printStackTrace(); } return ret; } public <T> T getProxy() { //增强类 Enhancer hancer = new Enhancer(); //对哪一个父类增强 hancer.setSuperclass(target.getClass()); //如何设置增强 hancer.setCallback(this); //返回并创建对象 return (T) hancer.create(); } } 

测试

同样的,我们在测试类里加上下面的代码,测试cglib代理:

@Resource
private CglibProxyHandler cglibProxyHandler;

@Test
public void testCglibProxy() throws Exception {
 //设置要代理的对象 cglibProxyHandler.setTarget(userService); //得到代理对象 UserService proxy = cglibProxyHandler.getProxy(); //代理对象执行方法 proxy.add(); } 

执行结果:

89_2.png

总结:

89_3.png

可以看到,JDK动态代理,代理的是实现了接口的类,而Cglib则没有这个要求,它是把要代理的类作为父类,然后创建一个代理类继承父类,复写并增强父类中的方法。

最后

欢迎大家关注我的公众号,共同学习,一起进步。加油

89_4.png

本文使用 tech.souyunku.com 排版

文章永久链接:https://tech.souyunku.com/33738

未经允许不得转载:搜云库技术团队 » Java中的动态代理

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们