先看一下代理模式,这个应该是设计模式中最简单的一个了,类图
代理模式最大的特点就是代理类和实际业务类实现同一个接口(或继承同一父类),代理对象持有一个实际对象的引用,外部调用时操作的是代理对象,而在代理对象的内部实现中又会去调用实际对象的操作
Java动态代理其实内部也是通过Java反射机制来实现的,即已知的一个对象,然后在运行时动态调用其方法,这样在调用前后作一些相应的处理,这样说的比较笼统,举个简单的例子
比如我们在应用中有这样一个需求,在对某个类的一个方法的调用前和调用后都要做一下日志操作,
一个普通的接口
[java] view plain copy print ? public interface AppService { public boolean createApp(String name); }
该接口的默认实现类
[java] view plain copy print ? public class AppServiceImpl implements AppService { public boolean createApp(String name) { System.out.println("App["+name+"] has been created."); return true; } }
日志处理器
[java] view plain copy print ? public class LoggerInterceptor implements InvocationHandler {//注意实现这个Handler接口 private Object target;//目标对象的引用,这里设计成Object类型,更具通用性 public LoggerInterceptor(Object target){ this.target = target; } public Object invoke(Object proxy, Method method, Object[] arg) throws Throwable { System.out.println("Entered "+target.getClass().getName()+"-"+method.getName()+",with arguments{"+arg[0]+"}"); Object result = method.invoke(target, arg);//调用目标对象的方法 System.out.println("Before return:"+result); return result; } }
外部调用
[java] view plain copy print ? public class Main { public static void main(String[] args) { AppService target = new AppServiceImpl();//生成目标对象 //接下来创建代理对象 AppService proxy = (AppService) Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new LoggerInterceptor(target)); proxy.createApp("Kevin Test"); } } 此外,可以使用Spring AOP 。