Spring AOP 杂谈

其实AOP的思想如今讲的已经不少了,自己没有什么难点,难的是AOP有本身的一套术语,而咱们常常被这套术语搞晕。术语没招,只能理解背诵了,尽管背诵很讨厌,可你们都这么说,不知道,就会被说晕。html

AOP思想:以下图,面向切面编程。就是“切“。执行本身的方法时,“在以前,以后,异常,返回,或者先后”都去顺便执行一下其余业务方法,切面就是其余业务方法。java

AOP术语以下图,简单示例编程

通知:通知定义了切面是什么以及什么时候使用,首先该通知方法实现了“作什么的代码业务逻辑”,而后肯定了在何时执行。ide

前置通知:在目标方法调用以前调用通知。测试

后置通知:在目标方法完成以后调用通知。this

返回通知:在目标方法成功执行以后调用通知。spa

异常通知:在目标方法抛出异常后调用通知。代理

环绕通知:通知包裹了被通知的方法,在被通知的方法调用以前和以后执行的自定义行为。htm

链接点:链接点 是在应用执行过程当中可以插入 切面 的一个点。这个点能够是调用方法时、抛出异常时、甚至修改一个字段时。切面代码能够利用这些点插入到应用的正常流程之中,并添加新的行为。对象

切点:切点就是在 “哪一个链接点或哪些链接点处”执行通知。定义了何处执行。

切面:通知+切点=切面 定义了 1.什么时候2.何处3.干什么 这三要素。

 

如下的两个概念定义了如何实现AOP

引入:引入容许咱们向现有的类添加新方法或属性。而无需修改这些现有的类的状况下,让他们具备新的行为和状态。

织入:是切面应用到目标对象并建立新的代理对象的过程。

这两个概念都是 “动做”

在目标对象的生命周期里能够有多个点进行织入(这里要了解一下  java类的运行过程)

编译期:切面在目标类编译时被织入,这种方式须要特殊的编译器。

类加载期:切面在目标类加载到JVM时被织入。这种方式须要特殊的类加载器(ClassLoader),它能够在目标类被引入应用以前加强该目标类的字节码。

运行期:切面在应用运行的某个时刻被织入。(通常状况下,在织入切面时,AOP容器会为目标对象动态的建立一个代理对象)

AOP实现

JAVA静态代理 : 代理对象和被代理对象实现相同的接口。

//接口

public interface StaticProxy {
         void action();

}

//被代理类

public class BProxy implements StaticProxy {

  @Override
  public void action() {
    System.out.println(BProxy.class.getName()+":作一些事情");
  }

}

//代理类

public class DProxy implements StaticProxy{

  StaticProxy BProxy;

  public DProxy() {
    BProxy = new BProxy();
  }

  @Override
  public void action() {
    System.out.println(DProxy.class.getName()+":先作一些事情");
    BProxy.action();
    System.out.println(DProxy.class.getName()+":再作一些事情");
  }

}

 

JDK动态代理:动态代理类的字节码在程序运行时由Java反射机制动态生成。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。一个类                               和一个接口实现。JDK动态代理的缺点:被代理类必须是实现接口的类。

//代理类 实现 InvocationHandler 

public class DynamicProxy implements InvocationHandler {

               private Object target;

               public DynamicProxy(Object target) {
                     this.target = target;
               }

               @Override
               public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                     //目标方法以前执行
                     System.out.println("do sth Before...");
                    //经过反射机制来调用目标类方法
                    Object result = method.invoke(target, args);
                    //目标方法以后执行
                    System.out.println("do sth After...\n");
                    return result;
               }

}

//供被代理类实现的接口

public interface userSrevices {

            public void addUser();

            public void deleteUser();

}

//实现接口的被代理类

public class userSrevicesImpl implements userSrevices{

    @Override
    public void addUser() {
      System.out.println("增长了一个用户");

    }

    @Override
    public void deleteUser() {
      System.out.println("删除了一个用户");
    }

}

//测试

public class test {

public static void main(String[] args) {
  //被代理类
  userSrevices target = new userSrevicesImpl();
  //代理类
  DynamicProxy handle = new DynamicProxy(target);
  //获取代理
  userSrevices proxy = (userSrevices)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handle);//Proxy类建立代理对象。
  //执行
  proxy.addUser();
  proxy.deleteUser();
}

}

Cglib动态代理:(目前还没有有实例。。。故引用一哈别的大神的讲解)http://www.javashuo.com/article/p-brwlvetb-gd.html

AspectJ实现:

 

未完待续。

相关文章
相关标签/搜索