以前做spring开发时,经常提起aop编程,事务等等概念,而其中有个设计模式很重要,就是代理模式,其又分为静态代理+动态代理两种。
静态:看图,暂不考虑。代理接口(Subject)、代理类(ProxySubject)、委托类即被代理者(RealSubject),被代理类直接作为参数传入代理处理器中,返回给接口对象,直接调用接口方法即可。
(借用网上图)
动态:(二话不说先上demo...)
1)接口:
public interface Person {
public String eat(String food);
public String sleep(String time);
}
2)被代理类:
public class Programmer implements Person {
@Override
public String eat(String food) {
System.out.println("吃吃吃宅宅宅~");
return "吃完打游戏~";
}
@Override
public String sleep(String time) {
System.out.println("睡你麻痹,起来嗨~");
return "在撸代码~";
}
}
3)代理类被调用时,自定义的处理器
public class PersonProxy implements InvocationHandler{
// 被代理类的实例,构造函数有多个参数时,method.invoke(obj,args)默认调用第一个的
Object obj = null;
public PersonProxy(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equals("eat")){
System.out.println("该方法已经被禁用,调用个毛线。。。");
return null;
}
System.out.println("开始调用:");
System.out.println("参数:"+StringUtil.join(args, ";"));
Object result = method.invoke(obj, args);
System.out.println("结束调用:");
return result;
}
}
4)测试:
public class PersonProxyTest {
public static void main(String[] args) {
Person programmer = new Programmer();
Person instance = (Person) Proxy.newProxyInstance(programmer.getClass().getClassLoader(), programmer.getClass().getInterfaces(), new PersonProxy(programmer));
System.out.println(instance.eat("水果"));
System.out.println(instance.sleep("23点"));
}
}
5)控制台打印日志:
该方法已经被禁用,调用个毛线。。。
null
开始调用:
参数:23点
睡你麻痹,起来嗨~
结束调用:
在撸代码~
解析:用动态代理模式,根据反射原理将(任意)代理类信息传入处理器,在处理器中,可针对Method做相应的操作(比如拦截或过滤参数等),可以简单的实现aop,更复杂的还有待研究。