jdk动态代理的实现流程(事务处理)

  • JDK动态代理的定义及功能
  • 动态代理就是使用JDK的反射机制创建对象的能力,创建的是代理类的对象,而不是类文件,不用写java文件。
  • 动态代理常用的有两类,jdk动态代理和cglib动态代理。将jdk动态代理必须有接口,且代理类对象必须实现接口。没有接口时使用cglib动态代理。
  • 主要的功能就是功能增强,在后面代码中我会加以说明。另外一种功能就是控制访问。
  • 动态代理的核心方法及思路理解
  • java.lang.reflect:反射包,里面有三个类,InvocationHandler , Method, Proxy。
  • 实现InvocationHandler接口,接口中有一个方法invoke(),它表示代理对象要执行的功能代码。
  • Method类:过Method可以执行某个目标类的方法,Method.invoke(),相当于静态代理中你要执行的方法的调用。
  • Proxy类:核心的对象,创建代理对象。我们通常设置对象都是使用new类的构造方法的方式,在动态代理中,我们使用Proxy类来代替new使用。
  • 它有三个参数:(1)ClassLoader loader:类加载器,负责向内存中加载对象。(2)Class<?>[] interfaces:获取目标对象的实现类接口。(3)InvocationHandler:代理类对象,表示代理类要完成的功能。
  • 代理类的代码实现与理解

实现代理类对象

我就用动态代理实现事务提交这个功能来举个栗子吧,推荐从测试类中开始开效果更好哦!

public class TransactionInvocationHandler implements InvocationHandler {

    private Object target;//用来指定要实现动态代理的实现类

    public  TransactionInvocationHandler(Object target){
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        SqlSession session = null;//获取SqlSession用来获取dao层的连接
        Object obj = null;//方法的返回值对象

        try{

            //获取dao层连接,关于这个不懂的同学可以去看看mybatis
            session = SqlSessionUtil.getSession();

            //处理业务逻辑,相当于静态代理中的方法执行。在它的前后部分可以编写其他方法,只要使用动态代理对象调用方法,就会执行你在invoke方法前后定义的方法
            obj = method.invoke(target, args);

            //处理业务逻辑完毕后,提交事务
            session.commit();

        }catch(Exception e){

            session.rollback();

            e.printStackTrace();
        }finally {
            //使用工具类关闭连接
            SqlSessionUtil.myClose(session);
        }

        return obj;
    }

    public Object getProxy(){

        //参数传入TransactionInvocationHandler这个类对象,用于获取target为目标类的动态代理对象
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);

    }
}

获取service层的动态代理对象的工具类,通过传入的service实现类获取该类动态代理对象

//参数service为service层实现某种方法的实现类对象
public class ServiceFactory {

	public static Object getService(Object service){

    return new TransactionInvocationHandler(service).getProxy();

	}
}

使用动态代理进行测试

public class MyApp {
    
    @Test
    public void test01() {

        //通过new的方式创建静态的service对象
        StudentService service = new StudentServiceImpl();

        //添加一条数据试试
        Student student = new Student();
        student.setId("1314225");
        student.setName("xihai");
        student.setAge(20);
        
        //由于sqlsession默认是不自动提交的,所以数据库中并没有插入数据,
        //具体的dao实现方法insert就自己写吧,我主要不是讲数据库方面内容,只是为了更好的理解才举例说明事务的处理
        service.insert(student);
    }
    
    @Test
    public void test02() {

        //使用jdk的Proxy创建动态代理对象
        StudentService serviceProxy = (StudentService) ServiceFactory.getService(new StudentServiceImpl());

        //测试添加操作
        Student student = new Student();
        student.setId("1314226");
        student.setName("shengge");
        student.setAge(21);
        //插入成功,由于动态代理对象中添加了事务提交功能。
        /*
        这里会去执行TransactionInvocationHandler对象中的invoke方法。
        对象的invoke方法的三个参数分别代表着serviceProxy代理对象,insert方法,student参数。
        */
        serviceProxy.insert(student);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值