静态代理与动态代理

代理模式

介绍

为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

1. 组成

抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。

2. 分类

2.1. 静态代理

所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。

2.2. 动态代理

实现阶段不用关心代理类,而在运行阶段才指定哪一个对象 ,并在内存中直接创建代理对象

3.静态代理演示

  • 实现儿子帮爸爸买烟

//抽象角色 接口
public interface Smoke{
	public void buy();
}
//真实角色 目标对象
public class Parent implements Smoke{
    @override
    public void buy(){
        System.out.println("爸爸的烟买好了");
   }
}
//代理角色
public class Son implements Smoke{
	private Smoke target;//多态调用
	public Son(Smoke target){
		this.target = target;
	}    
	@Override
	public void buy() {
        // 在代理中通过目标来调用真实行为
		target.buy();
	}
}

4.动态代理演示

静态代理中,需要手动编码Son代理类(Proxy)来实现Smoke接口,而动态代理可以在程序运行时,内存自动创建实现Smoke接口的代理,无需定义Son类.

主要功能 : 日志记录 性能统计 安全控制 事务处理

  • 改写买烟
  • 目标对象
public class Parent implements Smoke{
	@Override
	public void buy() {
		System.out.println("爸爸的烟买好了");
	}
}
public interface Smoke {
	public void buy();
}
//一个新的目标对象
public class Uncle implements Smoke{
	@Override
	public void buy() {
		System.out.println("叔叔的烟买好了");
	}
}
//目标对象Parent类及Smoke接口保留,Son代理类要实现InvocationHandler
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class Son implements InvocationHandler {

		private Object smoke;
		
		public ihandler(Object smoke){
			this.smoke = smoke;
		}
		
		@Override
		public Object invoke(Object proxy,Method method,Object[] args)
			throws Throwable{
			method.invoke(smoke, args);
			return null;
		}
	}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class xiyan{
	public static void main(String[] args) {
		//创建目标
		Parent parent = new Parent();
		Uncle uncle = new Uncle();

		InvocationHandler buy1 = new Son(parent);
		InvocationHandler buy2 = new Son(uncle);
		
		//使用newProxyInstance完成代理对象的创建
		Smoke dynamicProxy1 =(Smoke) Proxy.newProxyInstance(Parent.class.getClassLoader(), 
				 Parent.class.getInterfaces(), buy1);
		 Smoke dynamicProxy2 =(Smoke) Proxy.newProxyInstance(Uncle.class.getClassLoader(),
				 Uncle.class.getInterfaces(), buy2); 
		 
		 //代理完成
		 dynamicProxy1.buy();
		 dynamicProxy2.buy();
	}
上一篇:POJ-2006 Litmus Test 高精度


下一篇:JAVA面向对象(六)—— Java内部类、匿名内部类