zoukankan      html  css  js  c++  java
  • 动态代理

    1静态代理

    首先先看不使用代理

    public class Man implements Action {
        private String name;
    
        public Man(String name) {
            super();
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public void sayHello() {
            System.out.println(this.name + " say hello");
    
        }
    
        @Override
        public void eat(String food) {
            System.out.println("eat " + food);
            
        }
    
    }
    男人
    public interface Action {
        void sayHello();
    
        void eat(String food);
    }
    Action
    public class Man implements Action {
        private String name;
    
        public Man(String name) {
            super();
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public void sayHello() {
            System.out.println(this.name + " say hello");
    
        }
    
    }
    public interface Action {
        void sayHello()
        public static void main(String[] args) {
            Man man = new Man("jj");
            man.sayHello();
        }
    测试类

    上面是一个不使用静态代理的普通代码,但当我们想对sayHello方法增强其的功能时,比如增加一个openMouth行为时就不得不修改sayhello的代码逻辑,这不符合设计原则,所以我们可以使用代理模式进行代码修改。

    public class StaticProxy implements Action {
        private Man man;
    
        public StaticProxy(Man man) {
            super();
            this.man = man;
        }
    
        @Override
        public void sayHello() {
            // TODO Auto-generated method stub
            openMouth();
            man.sayHello();
        }
    
        private void openMouth() {
            System.out.println(man.getName() + "open mouth");
        }
    
    }
    静态代理
    public static void main(String[] args) {
            Man man = new Man("jj");
            StaticProxy sp = new StaticProxy(man);
            sp.sayHello();
        }
    测试类

    这样我们通过代理对象实现man对象的sayhello方法的增强后功能。这样的好处是,假如是Man每个方法都要增加日志功能,不可能在每个方法中加入log方法,我们可以在代理类的实现方法中调用Man的对应方法,后面再增加log逻辑。实现解耦合。

    我们可以总结一下静态代理 1.代理类和被代理类都要实现相同的接口(代理类要对被代理类进行功能增强的,不实现相同的接口,代理类就不知道增强什么功能) 2.代理类需要持有被代理类实例对象(功能增强是代理类和被代理类共同协作的结果)3.代理类进行实际的行为

    2.jdk动态代理

    public class DynamicProxyHandller implements InvocationHandler {
        private Object proxyed;
    
        public Object getProxyed() {
            return this.proxyed;
        }
    
        public void setProxyed(Object proxyed) {
            this.proxyed = proxyed;
        }
    
        // 获取代理实例
        public Object getProxyInstance() {
            return Proxy.newProxyInstance(proxyed.getClass().getClassLoader(), proxyed.getClass().getInterfaces(), this);
        }
    
        public DynamicProxyHandller(Object proxyed) {
            super();
            this.proxyed = proxyed;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
            dosomeBefore();
            method.invoke(proxyed, args);
            return null;
        }
    
        public void dosomeBefore() throws Exception {
            Field field = proxyed.getClass().getDeclaredField("name");
            field.setAccessible(true);
            System.out.println((String) field.get(proxyed) + " dosomeBefore");
    
        }
    
    }
    动态代理handler
    public static void main(String[] args) {
    
            Action man = new Man("jj");
            DynamicProxyHandller dp = new DynamicProxyHandller(man);
            Action ac = (Action) dp.getProxyInstance();
            ac.sayHello();
            ac.eat("apple");
    
        }
    测试类
    jj dosomeBefore
    jj say hello
    jj dosomeBefore
    jj eat apple

    从测试类中看出,我们先实例一个包含被代理类对象的动态代理handler(实现了InvocationHandler接口),然后通过handler实例一个代理对象,再通过代理对象去做相应的行为。这样整个动态代理就这样完成。

    那么这样的好处又是什么?

    首先静态代理和动态代理的区别很明显,静态代理有实际的代理类还需实现接口,动态代理只有一个handler,通过handler去实例一个代理对象。

    然后假如Action接口里面有很多方法,静态代理类需要实现这些方法,然而我仅仅就想给每个方法加个日志而已。动态代理就很好的解决了这个问题

    3.cglib动态代理

    JDK动态代理中被代理的类必须实现接口,假如被代理类没有实现接口,我们不能强行的给它增加接口,那么cglib动态代理就可以解决这个问题

    public class User {
    
        public void eat(String food) {
            System.out.println("eat " + food);
        }
    }
    public class UserInterceptor implements MethodInterceptor  {
    
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            // TODO Auto-generated method stub
             System.out.println("预处理");
            return proxy.invokeSuper(obj, args);
        }
    
    }
    方法intercepor
    public static void main(String[] args) {
    
            Enhancer enchancer = new Enhancer();// 字节码增强器
            enchancer.setSuperclass(User.class);// 设置被代理类为父类
            enchancer.setCallback(new UserInterceptor());// 设置回调
            User user = (User) enchancer.create();// 创建代理实例
            user.eat("葡萄");
        }
    测试类
  • 相关阅读:
    [极客大挑战 2019]EasySQL
    BUUCTF-[强网杯 2019]随便注-wp
    BUUCTF-[HCTF 2018]WarmUp-wp
    wp-2017ssrfme
    < 算法笔记(晴神宝典)
    < python音频库:Windows下pydub安装配置、过程出现的问题及常用API >
    < JAVA
    < 博客园自定义皮肤装饰代码
    <编译原理
    < AlexNet
  • 原文地址:https://www.cnblogs.com/ljjnbpy/p/9981218.html
Copyright © 2011-2022 走看看