zoukankan      html  css  js  c++  java
  • 代理模式



    1. 代理模式(Proxy Pattern)

    我们需要的东西通过代理对象拿去,而不需要去真正的实现对象,前提是代理对象和被代理对象需要实现相同的接口,而代理在这里相当于中介,并且我们也需要创建一个代理对象



    2. 代理的实现


    1.2 静态代理

    有点类似装饰者模式,话不多说上代码


    1.共同的接口

    public interface Dog {
    	abstract void eat();
    }
    

    2.实现类

    public class MyDog implements Dog {
    
    	public void eat() {
    		System.out.println("狗吃肉");
    	}
    }
    

    3.代理类

    public class DogProxy implements Dog {
    
    	private Dog dog;
    	
    	public DogProxy (Dog dog) {
    		this.dog = dog;
    	}
        
        public void WashHand(){
    		System.out.println("吃肉前洗手");
    	}
    
    	public void eat() {
            WashHand();
    		dog.eat();
    	}
    }
    

    4.代理实现

    public static void main(String[] args) {
    		
        Dog mydog = new MyDog();
        mydog = new WashHandDog(mydog);
        mydog.eat();
    }
    
    吃肉前洗手
    狗吃肉
    


    1.3 动态代理

    动态代理也是基于接口实现的,所以使用上面的接口,该接口增多一个抽象方法用于下面测试

    这里重申一下,生成的代理对象是要强转成接口的,接口,接口!!!


    public class MyDog implements Dog {
    
    	public void eat() {
    		System.out.println("狗吃肉");
    	}
    
        //测试方法
    	public void jump() {
    		System.out.println("狗会跳");
    	}
    }
    

    这里需要先了解两个方法

    • Proxy类的newInstance() ——生成代理对象

    该方法有三个参数,第一个是被代理对象的类加载器,第二个是被代理对象的接口,第三个是处理器也就是下面的InvocationHandler()

    • InvocationHandler()——处理器

    在代理对象上调用任何方法都会被这个处理器拦截


    具体实现

    public static void main(String[] args) {
    	
        //被代理对象
        Dog mydog = new MyDog();
        
        //生成代理对象,这里InvocationHandler采用匿名函数写法
        Dog ProxyDog = (Dog) Proxy.newProxyInstance(mydog.getClass().getClassLoader(), mydog.getClass().getInterfaces(),new InvocationHandler(){
    
    		//重写方法
    		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    			//只增强eat方法
    			if(method.getName().equals("eat")){
    				System.out.println("吃肉前洗手");
    				method.invoke(mydog, args);
    			}else{
    				method.invoke(mydog, args);
    			}
    			return null;
    		}
        });
        
        //代理对象调用增强函数
    	ProxyDog.eat();
    	System.out.println("-------测试方法--------");
    	//没有增强
    	ProxyDog.jump();
    }
    
    吃肉前洗手
    狗吃肉
    -------测试方法--------
    狗会跳
    


    • Spring的AOP切面编程也是可以用动态代理来实现的,想要了解AOP的 戳这里

    回来填坑,之前一直不理解为什么代理对象调用方法就能有方法实现,后面参考了 廖雪峰 的博客豁然开朗 ,这里十分万分感谢

    //动态代理实际上是JDK在运行期动态创建class字节码并加载的过程,它并没有什么黑魔法,把上面的动态代理改写为静态实现类大概长这样
    
    
    public class HelloDynamicProxy implements Hello {
        InvocationHandler handler;
        
        //传入了之前写的处理器
        public HelloDynamicProxy(InvocationHandler handler) {
            this.handler = handler;
        }
        
        //看这里这里没错就是这里!!!,方法中写入invoke,这里就实现调用方法,困惑了我好久
        public void morning(String name) {
            handler.invoke(
               this,
               Hello.class.getMethod("morning"),
               new Object[] { name });
        }
    }
    


  • 相关阅读:
    OLTP和OLAP区别
    JAVA实现文件树
    商务智能及其实现模型
    Java打印程序设计
    J2EE的昨天,今天,明天
    常用jar包之commonslang使用
    CRM与ERP整合的六个切入点
    常用jar包之commonscollection使用
    软件安全技术
    常用jar包之commonsbeanutils使用
  • 原文地址:https://www.cnblogs.com/Howlet/p/12023801.html
Copyright © 2011-2022 走看看