spring框架学习之路(一)-入门基础(2)-动态代理和AOP(面向切面编程)

来源:互联网 发布:咖啡入门 知乎 编辑:程序博客网 时间:2024/04/30 13:13

  spring框架学习之路(一)-入门基础(1)-IOC(控制反转)&DI(依赖注入);
  之前写了关于spring的内核IOC&DI的一些内容,现在接着写spring的另一个重要概念AOP。
  AOP(Aspect Oriented Programming):面向切面编程。与OOP(面向对象编程)自上而下的程序结构不同的是,AOP是针对于程序切面。
  比如日志记录,我们需要对多个类中的多个方法执行前或执行后进行记录日志,如果我们对每一个方都添加相同的记录日志的代码,就违反了DRY(Don’t repeat yourself)原则。所以出现了AOP,AOP就是在程序的水平结构上进行整体程序设计,而不需要针对每一个方法进行设计。
  要了解AOP,就必须了解“代理模式”(不了解的百度吧…设计模式的坑以后填…),而AOP利用的就是“动态代理”。
  简单来说,AOP主要就是动态生成和不同的“真实角色”相对应的“代理角色”。核心就是InvocationHandler接口 和Proxy.newProxyInstance() 方法。
  老规矩,举个栗子~~~

//抽象角色public interface AbsRole {      void doActive();}//真实角色public class RealRole implements AbsRole {    @Override    public void doActive() {        System.out.println("active from real role!");    }}

  然后创建一个InvocationHandler,InvocationHandler只有一个invoke()方法,而我们只需要在里面实现method.invoke(obj, args);就可以调用 对象obj的方法method,此方法参数为args,返回值为res。
  在这条语句前后加入逻辑,就可以实现每次执行方法method时都会附带执行前后逻辑。(这里就是前后的两条输出语句)

import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class ProxyRole implements InvocationHandler {    private Object obj;    public ProxyRole(Object obj) {        super();        this.obj = obj;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args)            throws Throwable {        System.out.println("previous method");        Object res=method.invoke(obj, args);        System.out.println("after method");        return res;    }   }

main方法的执行方法为:

    public static void main(String[] args) {            RealRole real=new RealRole();               AbsRole abs=(AbsRole) Proxy.newProxyInstance(RealRole.class.getClassLoader(), RealRole.class.getInterfaces(), new ProxyRole(real));        abs.doActive();    }

大体逻辑执行过程就是:
  通过Proxy.newProxyInstance()方法生成一个对象,此对象继承$Proxy0类,并实现真实角色的接口,并且此对象拥有一个InvocationHandler h对象的应用。然后用一个抽象角色abs引用这个对象。
  执行abs.doActive()时,此对象在doActive()方法中的具体实现就是调用h.invoke()方法,这样在h.invoke()中就实现了对真实角色方法的执行。
  **另外需要注意的是,在ProxyRole类中
  public Object invoke(Object proxy, Method method, Object[] args)
  方法中的proxy对象不是真实角色的应用,而是动态生成的代理角色(就是那个继承自$Proxy0类的对象)的引用。**

阅读全文
0 0
原创粉丝点击