随机名言

代理模式



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 });
    }
}


posted @ 2019-12-11 17:19  Howlet  阅读(286)  评论(0编辑  收藏  举报

Copyright © By Howl