• 代理模式之动态代理


    动态代理,

             1)代理对象,不需要实现接口;

             2)代理对象的生成,是利用JDKAPI, 动态的在内存中构建代理对象(需要我们指定创建 代理对象/目标对象 实现的接口的类型;);

             3)  动态代理, JDK代理, 接口代理;

    JDK中生成代理对象的API:

    |-- Proxy
    
             static Object newProxyInstance(
    
                        ClassLoader loader,       指定当前目标对象使用类加载器
    
                       Class<?>[] interfaces,     目标对象实现的接口的类型
    
                       InvocationHandler h       事件处理器
    
    ) 

    思考:

             有一个目标对象,想要功能扩展,但目标对象没有实现接口,怎样功能扩展?

             Class  UserDao{}

             // 子类的方式

             Class subclass  extends  UserDao{}                                    

             以子类的方式实现(cglib代理)


    package loaderman.b_dynamic;
    
    // 接口
    public interface IUserDao {
    
        void save();
        
    }
    package loaderman.b_dynamic;
    
    /**
     * 目标对象
     *
     */
    public class UserDao implements IUserDao{
    
        @Override
        public void save() {
            System.out.println("-----已经保存数据!!!------");
        }
    
    }
    package loaderman.b_dynamic;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    /**
     * 给所有的dao创建代理对象【动态代理】
     *
     * 代理对象,不需要实现接口
     *
     */
    public class ProxyFactory {
    
        // 维护一个目标对象
        private Object target;
        public ProxyFactory(Object target){
            this.target = target;
        }
    
        // 给目标对象,生成代理对象
        public Object getProxyInstance() {
            return Proxy.newProxyInstance(
                    target.getClass().getClassLoader(),
                    target.getClass().getInterfaces(),
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args)
                                throws Throwable {
                            System.out.println("开启事务");
    
                            // 执行目标对象方法
                            Object returnValue = method.invoke(target, args);
    
                            System.out.println("提交事务");
                            return returnValue;
                        }
                    });
        }
    }
    package loaderman.b_dynamic;
    
    public class App {
    
        public static void main(String[] args) {
            // 目标对象
            IUserDao target = new UserDao();
            // 【原始的类型 class cn.loaderman.b_dynamic.UserDao】
            System.out.println(target.getClass());
    
            // 给目标对象,创建代理对象
            IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
            // class $Proxy0   内存中动态生成的代理对象
            System.out.println(proxy.getClass());
    
            // 执行方法   【代理对象】
            proxy.save();
        }
    }
  • 相关阅读:
    sqlserver 智能提示插件
    支付相关-算法知识2
    支付相关-算法知识1
    支付相关-证书知识学习4
    支付相关-证书知识学习3
    支付相关-证书知识学习2
    getID3类的学习使用
    ThinkPHP 的 Vender的简单实用
    postman的简单使用
    js 实现点击复制文本内容
  • 原文地址:https://www.cnblogs.com/loaderman/p/10042724.html
Copyright © 2020-2023  润新知