资讯专栏INFORMATION COLUMN

使用动态代理简单模拟一下spring的事务管理

shaonbean / 1555人阅读

摘要:我们平时用到的的事务管理的都是的实例把事务操作放到了代理类中统一或本身就是一个代理类,在调用指定方法前后添加一系列操作

按照平时写代码的习惯,我们会定义一个service接口

package com.proxy.test;
public interface UserService {
    public void sayHello(String word);
}

接着是实现类

package com.proxy.test;
public class UserServiceImpl implements UserService{
    @Override
    public void sayHello(String word) {
        System.out.println("执行dao的删除操作,添加一个用户:" + word);
        System.out.println("执行dao的删除添加,删除一个用户:" + word);
    }
}

我们的目的是,执行sayHello中的添加删除操作时,让这几条sql语句同时提交(commit)或同时回滚(rollback),下面我们用动态代理的方式,实现这个功能:
自定义一个代理管家,帮我们创建代理类,需要实现InvocationHandler接口(必须)

package com.proxy.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MyProxyManager implements InvocationHandler {
    private Object target;
    public Object bind(Object target){
        this.target = target;
        /*
         * Proxy.newProxyInstance 会返回一个代理对象
         * target.getClass() --> 被代理对象的ClassLoader,这里实际对应UserServiceImpl类
         * target.getClass().getInterfaces() --> 被代理对象实现的接口列表(UserService),指定之后,代理对象就可以使用其接口中的方法了
         * this -- 表示的是当这个动态代理对象在调用方法的时候,会通过哪个InvocationHandler,这里实际是MyProxyManager这个类
         */
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    /**
     * 我们通过MyProxyManager创建出来的代理对象在调用自己的方法时,
     * 会通过invoke这个方法进行调用,而不是直接调用
     * @param proxy 被代理对象
     * @param method 被代理对象执行的方法
     * @param args 被代理对象执行的方法所需要的参数
     *
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) {
        System.out.println("我是动态代理对象");
        System.out.println("准备进入事务..");
        Object result = null;
        try{
            // 执行被代理对象自己的方法
            result = method.invoke(target, args);
        }catch(Exception e){
            // 如果有错误,执行数据库的rollBack方法
            System.out.println("执行rollBack");
        }
        // 如果没错,执行数据库的commit方法
        System.out.println("执行commit");
        System.out.println("-----------------------");
        return result;
    }
}

测试代码

public static void main(String[] args) {
    MyProxyManager manager = new MyProxyManager();
    // 创建UserService的代理对象
    UserService userService = (UserService) manager.bind(new UserServiceImpl());
    userService.sayHello("lalala");
}

运行看一下效果:

我是动态代理对象
准备进入事务..
执行dao的删除操作,添加一个用户:lalala
执行dao的删除添加,删除一个用户:lalala
执行commit

这里只是使用打印语句简单模拟了数据库的操作,没有真正连接数据库操作,有空的童鞋可以实际操作一下。

我们平时用到的spring的事务管理、springmvc的interceptor都是aop的实例
spring把事务操作放到了代理类中统一commit或rollback
interceptor本身就是一个代理类,在调用指定方法前后添加一系列操作

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/76463.html

相关文章

  • Spring AOP实现原理

    摘要:使用与的静态代理不同,使用的动态代理,所谓的动态代理就是说框架不会去修改字节码,而是在内存中临时为方法生成一个对象,这个对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。 AOP(Aspect Orient Programming),我们一般称为面向方面(切面)编程,作为面向对象的一种补充,用于处理系统中分布于各个模块的横切关注点,比如事务管理、日志、缓存...

    ephererid 评论0 收藏0
  • Java反射-动态代理

    摘要:动态代理有多种不同的用途,例如,数据库连接和事务管理用于单元测试的动态模拟对象其他类似的方法拦截。调用序列和下面的流程类似单元测试动态对象模拟利用动态代理实现单元测试的动态存根代理和代理。框架把包装成动态代理。 使用反射可以在运行时动态实现接口。这可以使用类java.lang.reflect.Proxy。这个类的名称是我将这些动态接口实现称之为动态代理的原因。动态代理有多种不同的用途,...

    Acceml 评论0 收藏0
  • 设计模式之代理模式

    摘要:下面我们通过玩英雄联盟代练的例子来说明下登录游戏赢下了一局英雄联盟,获得了金币测试结果登录游戏赢下了一局英雄联盟,获得了金币可以这样理解,自己写代理类的方式就是静态代理。 前言 刚上大学那会,英雄联盟火的一塌糊涂,当时每天都想着升到30级开启排位之旅。可是升到30级需要大把的时间不说,这时候匹配到的人,水平过于参差不齐,问候你全家的事经常发生,那个时候就想要是能有个代练帮我升到30级该...

    xuweijian 评论0 收藏0
  • Java面试 32个核心必考点完全解析

    摘要:如问到是否使用某框架,实际是是问该框架的使用场景,有什么特点,和同类可框架对比一系列的问题。这两个方向的区分点在于工作方向的侧重点不同。 [TOC] 这是一份来自哔哩哔哩的Java面试Java面试 32个核心必考点完全解析(完) 课程预习 1.1 课程内容分为三个模块 基础模块: 技术岗位与面试 计算机基础 JVM原理 多线程 设计模式 数据结构与算法 应用模块: 常用工具集 ...

    JiaXinYi 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<