代理模式

105 阅读2分钟

生活场景

想象你现在正准备租房子。你有两个选择,第一个是直接找房东租房,一个房东只有一套房子出租,你每找到一个房东只能看一套房子;第二个你可以找到中介。中介是房东的代理人,并且一个中介手里面往往有多套房子,这是不是扩展了房东只有一套房的功能?

代理模式为一个对象提供一个替身,以提供对这个对象的访问。即通过代理对象访问目标对象,这样做的好处是:可以在目标对象的实现基础上,为其增加额外的功能,即扩展目标对象的功能。
代理模式主要分为两种,一种是静态代理,一种是动态代理。

主要角色

  1. 被代理角色
  2. 代理角色

静态代理

优点:在不修改目标对象的前提下,能通过代理对象对目标对象进行扩展。 缺点:因为代理对象和目标对象都需要实现一样的接口,所以会有很多的代理类,一旦接口增加方法的话,目标对象和代理对象都要维护。

动态代理

  1. JDK动态代理 === 要求被代理的类必须要实现一个接口
public class TeacherDaoProxy {

    private Object target;

    public TeacherDaoProxy(Object target){
        this.target = target;
    }

    public Object getProxyInstance(){

        Object o = 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("JDK动态代理开始.......");
                        Object obj = method.invoke(target, args);
                        return obj;
                    }
                });
        return o;

    }
}

最重要的就是两个类:Proxy和InvocationHandler。
Proxy用来返回一个代理对象,InvocationHandler用来实现对被代理对象的增强。

Cglib代理 ====== 不要求被代理类实现一个接口

public class ProxyFactory implements MethodInterceptor {


	private Object target;

	public ProxyFactory(Object target) {
		this.target = target;
	}


	public Object getProxyInstance() {
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(target.getClass());
		enhancer.setCallback(this);
		return enhancreaer.create();
	}
	

	@Override
	public Object intercept(Object arg0, Method method, Object[] args, MethodProxy arg3) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("Cglib动态代理开始~~ʼ");
		Object returnVal = method.invoke(target, args);
		System.out.println("Cglib动态代理结束~~");
		return returnVal;
	}

}

重点是两个:Enhancer 和 实现MethodInterceptor并重写intercept方法。
Enhancer类用来返回一个代理对象,intercept方法中用来实现对代理对象方法的增强。