从代理模式到Spring AOP

什么是代理模式

           假如我喜欢上隔壁班的翠花,但是我没胆量向她送花,这时候我需要一个铁杆哥们帮我做这件事, 很明显这哥们是个代理,是去执行任务的,但是花实际上是我“送”的,代理和我一样会送花这个动作,直接上代码。

  1 public interface IProcess {
  2     void SendFlower();
  3 }
  1 public class Studnet1 implements IProcess {
  2 
  3     @Override
  4     public void SendFlower() {
  5         System.out.println("my name is Studnet1 , the flower is for you ");
  6     }
  7 }
  8 
  9 
 10 
 11 
 12 
 13 public class ProxyStudent implements IProcess {
 14 
 15     private IProcess targetObj;
 16 
 17     public ProxyStudent(IProcess targetObj) {
 18         this.targetObj = targetObj;
 19     }
 20 
 21     @Override
 22     public void SendFlower() {
 23         System.out.println("check it before send");
 24         targetObj.SendFlower();
 25         System.out.println("check it after send");
 26     }
 27 }
 28 
  1 public class ProcessFactory {
  2     public static IProcess getProcess(){
  3         return  new Studnet1();
  4     }
  5 }
  6 
  1 public class Main {
  2 
  3     public static void main(String[] args) {
  4         IProcess ProxyObj = ProcessFactory.getProcess();
  5         ProxyObj.SendFlower();
  6     }
  7 }

        运行结果:

  1 check it before send
  2 my name is Studnet1 , the flower is for you
  3 check it after send

        很开心,终于把花送出去了,可以见到调用代理者的SendFlower方法,实际上是我的SendFlower 方法,打到我需要送花的目的,同时这铁哥们人缘非常好,其他的同学也需要他来帮忙 , Student2, Student3 , Student4 也需要这铁哥们,

并且他们的要求不只是送花,还可能邀请看电影….等等,那么ProcessFatory 也要改写,另外假如我不止想送花这个动作,需要添加方法到接口上,那么其他类相应的也要改动。

  1 public class ProcessFactory {
  2     public static IProcess getProcess(){
  3         return  new Studnet1();
  4     }
  5 
  6     public static IHold getHold(){
  7         return  new Studnet2();
  8     }
  9 
 10     public static IMovie getMovier(){
 11         return  new Studnet3();
 12     }
 13 
 14     .....
 15 
 16 }

        显然这样的每次一个新的一个需求都需要创建一个对象,很不合理,于是就出现了动态代理。

 

动态代理

        先上代码,新建一个类,

  1 public class StuInvocationHandler<T> implements InvocationHandler {
  2     T target;
  3 
  4     public StuInvocationHandler(T target) {
  5         this.target = target;
  6     }
  7 
  8 
  9     @Override
 10     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
 11         System.out.println("this is a proxy method");
 12         System.out.println("check it before sending");
 13         Object result = method.invoke(target, args);
 14         System.out.println("check it after sending ");
 15         return result;
 16     }
 17 }

      调用,输出结果:

  1 public class Main {
  2 
  3     public static void main(String[] args) {
  4         IProcess student1 = ProcessFactory.getProcess();
  5         InvocationHandler handler = new StuInvocationHandler<IProcess>(student1);
  6         IProcess ProxyStudent = (IProcess) Proxy.newProxyInstance(IProcess.class.getClassLoader(), new Class<?>[]{IProcess.class}, handler);
  7         ProxyStudent.SendFlower();
  8 
  9     }
 10 }
  1 this is a proxy method
  2 check it before sending
  3 my name is Studnet1 , the flower is for you
  4 check it after sending

        我们似乎看不到了代理类,实际上StuInvocationHandler就是我们的代理类,这时无论代理谁都可以进行操作,动态代理运用了java一个重要的特性—“反射” 。 可以查看这篇文章,http://https://www.cnblogs.com/gonjan-blog/p/6685611.html。 我们需要知道两点:

  • 代理类调用方法使用了反射
  • 代理类继承了Proxy , 实现了被代理的接口,对应例子中的 IProcess , 由于java是单继承,所以也就决定了java动态代理只能对接口进行代理。

      

       再回想一下,调用invoke方法前后我们都是可以进行其他操作的,实际上这就是Spring里的AOP,Spring的AOP实现其实也是用了Proxy和InvocationHandler这两个东西的。

参考文章:

1.https://www.cnblogs.com/gonjan-blog/p/6685611.html

2.https://www.zhihu.com/question/20794107

猜你喜欢

转载自www.cnblogs.com/Benjious/p/9302016.html