代理模式

介绍

对于被代理人来说,这件事情是一定要做的,但是我自己又不想做或者没有时间做。
对于代理人而言,需要获取到被代理的人个人资料,只是参与整个过程的某个或几个环节。

办事要求人,所以找代理。例如:中介、游戏代打、售票黄牛、婚介、经纪人、快递、事务代理、非侵入式日志监听

程序

jdk代理

public class ZhongJie implements InvocationHandler {

    private Person target;

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("----中介帮"+this.target.getClass()+"找房");
        return method.invoke(this.target,args);
    }

    public Object getInstance(Person target){
        this.target=target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }
}
public interface Person {
    void findHouse();
}
public class XiaoMing implements Person {
    @Override
    public void findHouse() {
        System.out.println("小明找房");
    }
}
public class XiaoLi implements Person {
    @Override
    public void findHouse() {
        System.out.println("小李找房");
    }
}

测试下:

 Person p = (Person) new ZhongJie().getInstance(new XiaoMing());
        p.findHouse();
        Person p1 = (Person) new ZhongJie().getInstance(new XiaoLi());
        p1.findHouse();

结果如下:

CGLIB代理

public class Meipo implements MethodInterceptor{
	public Object getInstance(Class clazz) throws Exception{

		Enhancer enhancer = new Enhancer();
		//把父类设置为谁?
		//这一步就是告诉cglib,生成的子类需要继承哪个类
		enhancer.setSuperclass(clazz);
		//设置回调
		enhancer.setCallback(this);

		//第一步、生成源代码
		//第二步、编译成class文件
		//第三步、加载到JVM中,并返回被代理对象
		return enhancer.create();
	}

	//同样是做了字节码重组这样一件事情
	//对于使用API的用户来说,是无感知
	@Override
	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
		System.out.println("我是GP媒婆:" + "得给你找个异性才行");
		System.out.println("开始进行海选...");
		System.out.println("------------");
		//这个obj的引用是由CGLib给我们new出来的
		//cglib new出来以后的对象,是被代理对象的子类(继承了我们自己写的那个类)
		//OOP, 在new子类之前,实际上默认先调用了我们super()方法的,
		//new了子类的同时,必须先new出来父类,这就相当于是间接的持有了我们父类的引用
		//子类重写了父类的所有的方法
		//我们改变子类对象的某些属性,是可以间接的操作父类的属性的
		proxy.invokeSuper(obj, args);
		System.out.println("------------");
		System.out.println("如果合适的话,就准备办事");
		return null;
	}


public class XiaoYang {


	public void findLove(){
		System.out.println("肤白貌美大长腿");
	}
}

测试下:

try {
			XiaoYang obj = (XiaoYang)new Meipo().getInstance(XiaoYang.class);
			obj.findLove();
		} catch (Exception e) {
			e.printStackTrace();
		}

结果:

posted @ 2019-04-18 15:24  梅溪梦窗  阅读(105)  评论(0)    收藏  举报