ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring中的代理模式(jdk为主)

2022-04-04 13:02:11  阅读:147  来源: 互联网

标签:jdk 对象 Spring dynamic 代理 接口 user tManager


代理的分类:静态代理 动态代理(jdk动态代理/cglib动态代理)

    1. 静态代理:

    描述:有多个业务类,就有多少个代理类,代理类,在编译之前就已经存在了,和业务类同时存在。

    静态代理:

       1、需要知道核心类(被代理类)是哪一个类,并且有什么方法。 

       2、非核心的代码需要重复写多次,显得代码的结构臃肿,形成代码冗余。

       3、非核心类(代理类)需要实现核心类(被代理类)实现的接口,也就是他们需要实现共同的接口,但是以核心类实现的接口(被代理类)为准。

    l目地是将业务代码与日志代码完全分离,实现松散耦合.

    l代理对象与被代理对象必须实现同一接口,在代理对象中实现与日志记录的相关服务,并在需要的时候呼叫被代理对象,而被代理对象只保留业务代码.

     

    静态代理的弊端:

    一个代理接口只能服务于一种类型的对象.对于稍大点的项目根本无法胜任.

    静态代理的实现:

    1、先确定核心类(被代理的类)。

    其中的方法:

    @Resource
    private UserDao userDao;

    public void inserts(User user) throws SQLException {
        userDao.insert(user);
        SpringCha springCha = new SpringCha();
        springCha.setHabit("先吃再睡");
        springCha.setHobby("吃喝睡");
        userDao.insert(springCha);
    }

     

    2、在去编写非核心类。

    事务处理:

    @Resource
    private TManager tManager;
    @Resource
    private UserServiceImpl1 userServiceImpl1;
    public void inserts(User user) throws SQLException {
        try {
            tManager.closeCommit();
            userServiceImpl1.inserts(user);
            tManager.commit();
        } catch (SQLException e) {
            e.printStackTrace();
            tManager.rollBack();
        }

    }

     

    3、在使用非核心类。

     

  1. 动态代理(jdk):

    1. 利用静态代理中的核心类(这个核心类是静态和动态所需的)
    2. 在创建一个类(xxxProxy)来实现InvocationHandler接口
    3. 在实现InvocationHandler后,进行编写里面的方法

    //使用注解把实现动态代理的类注入spring容器中
    @Component
    public class Dynamic implements InvocationHandler {
        @Resource(name = "userServiceImpl1")
        private Object object;

        /**
         * 用来在测试类中进行测试时获取实例,以及接口
         * UserService o = (UserService)Proxy.newProxyInstance(
         *                 dynamic.getObject().getClass().getClassLoader(),
         *                 dynamic.getObject().getClass().getInterfaces(),
         *                 dynamic);
         * @return
         */

     

    /**

         * 当用户调用对象中的每个方法时都通过下面的方法执行,方法必须在接口

         * proxy 被代理后的对象

         * method 将要被执行的方法信息(反射)

         * args 执行方法时需要的参数

         */


        public Object getObject() {
            return object;
        }

        /**
         * 事务处理,来处理后续数据库操作可能出现的错误
         */
        @Resource
        private TManager tManager;

        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object invoke=null;
            try {
    //            关闭自动提交事务
                tManager.closeCommit();
    //            返回我们需要动态代理的实现类
                invoke= method.invoke(object, args);
    //            手动提交事务
                tManager.commit();
            } catch (SQLException e) {
                e.printStackTrace();
    //            事务回滚
                tManager.rollBack();
            }
            
            return invoke;
        }
    }

     

    1. 在使用(在测试中使用)

    /**
     * 动态代理
     */
    @Resource
    private Dynamic dynamic;

    @Test
    public void testInsert2() throws SQLException {

    // 在使用动态代理,在返回实现类但是需要使用它的接口

    /**

    * 通过Proxy的newProxyInstance方法来创建我们的代理对象,我们来看看其三个参数

          * 第一个参数 dynamic.getObject().getClass().getClassLoader(),我们这里使用handler这个类的ClassLoader对象来加载我们的代理对象

          * 第二个参数dynamic.getObject().getClass().getInterfaces(),是为代理对象提供的接口是真实对象所实行的接口,表示我要代理的是该真实对象,这样我就能调用这组接口中的方法了

          * 第三个参数dynamic,将这个代理对象关联到了上方的 InvocationHandler 这个对象上

          */


        UserService o = (UserService)Proxy.newProxyInstance(
                dynamic.getObject().getClass().getClassLoader(),
                dynamic.getObject().getClass().getInterfaces(),
                dynamic);

        User user = new User();
        user.setName("枫");
        user.setPassword("201619");
        o.inserts(user);
    }

     

    并且在使用实现动态代理有一个问题:被代理的类必须实现接口,未实现接口则没办法完成动态代理。而且在动态代理类中也是只能去处理一个被代理类。

标签:jdk,对象,Spring,dynamic,代理,接口,user,tManager
来源: https://www.cnblogs.com/qinsir817/p/16098871.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有