在软件系统中,会有多份代码区用到同一段代码,在维护上面造成巨大地麻烦,如果有10000个地方需要对相同的代码段进行修改,工作量将会大大增加。于是有人提出了,将相同的代码段用一个方法包起来,到用到的时候再调用,但是这样就造成了,多份代码区与该方法的一个耦合~~~最好的解决就是,不在这些代码区以硬编码方式进行对相同代码的调用,交给代理去做~~
看实例:
由于JDK动态代理只能创建指定接口的动态代理,所以,先创建一个接口。
public interface Dog { //info方法声明 public void info(); //run方法声明 public void run(); }
简单的实现类
public class GunDog implements Dog { //info方法实现,仅仅打印一个字符串 public void info() { System.out.println("我是一只猎狗"); } //run方法实现,仅仅打印一个字符串 public void run() { System.out.println("我奔跑迅速"); } }
接下来就是相同的代码段,也就是不用在用硬编码方式调用的代码
public class DogUtil { //第一个拦截器方法 public void method1() { System.out.println("=====模拟第一个通用方法====="); } //第二个拦截器方法 public void method2() { System.out.println("=====模拟通用方法二====="); } }
接下来就是代理类
public class MyInvokationHandler implements InvocationHandler { //需要被代理的对象 private Object target; public void setTarget(Object target) { this.target = target; } //执行动态代理对象的所有方法时,都会被替换成执行如下的invoke方法 public Object invoke(Object proxy, Method method, Object[] args) throws Exception { DogUtil du = new DogUtil(); //执行DogUtil对象中的method1。 du.method1(); //以target作为主调来执行method方法 Object result = method.invoke(target , args); //执行DogUtil对象中的method2。 du.method2(); return result; } }
代理类的好处就是每当被代理的对象调用自己的方法时都会被替换成执行代理类的invoke方法,这个时候就将相同的代码段被调用进来~~~
接下来就是生成动态代理类,其实就是一个工厂~~~
public class MyProxyFactory { //为指定target生成动态代理对象 public static Object getProxy(Object target) throws Exception { //创建一个MyInvokationHandler对象 MyInvokationHandler handler = new MyInvokationHandler(); //为MyInvokationHandler设置target对象 handler.setTarget(target); //创建、并返回一个动态代理 return Proxy.newProxyInstance(target.getClass().getClassLoader() , target.getClass().getInterfaces(), handler); } }
测试一下~~
public class Test { public static void main(String[] args) throws Exception { //创建一个原始的GunDog对象,作为target Dog target = new GunDog(); //以指定的target来创建动态代理 Dog dog = (Dog)MyProxyFactory.getProxy(target); dog.info(); dog.run(); } }
结果如下~~
可以看到,每次调用自己的方法时,都是按照代理类的invoke方法的顺序执行,可以看出动态代理对象很灵活地解决了耦合问题。