一、編譯期(AspectJ)java
二、類加載時(AspectJ 5+)ide
三、運行時(Spring AOP)this
運行時織入是怎麼實現的?代理
一、從靜態代理到動態代理code
二、動態代理 分爲 基於接口代理實現和基於繼承代理實現對象
客戶端經過代理對象漸漸與目標對象打交道,反之,目標對象委託代理對象與客戶端進行交流。所以代理對象能夠在目標對象方法先後,作出額外的操做,這就是代理AOP實現的原理。繼承
代理模式類圖接口
public class RealSubject implements Subject { @Override public void request() { System.out.println(" execute real subject request"); } }
public class Proxy implements Subject { private RealSubject realSubject; public Proxy(RealSubject realSubject) { this.realSubject = realSubject; } @Override public void request() { System.out.println(" before 織入邏輯"); try { realSubject.request(); } catch (Exception e) { System.out.println("ex:"+e.getMessage()); e.printStackTrace(); } finally { System.out.println(" after 織入邏輯"); } } }
public interface Subject { public void request(); }
public class Client { public static void main(String[] args) { Subject subject = new Proxy(new RealSubject()); subject.request(); } }
import cn.evchar.proxy.aop.RealSubject; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class JdkProxySubject implements InvocationHandler { private RealSubject realSubject; public JdkProxySubject(RealSubject realSubject) { this.realSubject = realSubject; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object res = null; System.out.println("before"); try { res = method.invoke(realSubject,args); } catch (Exception e) { System.out.println("ex: "+e); throw e; } finally { System.out.println("after"); } return res; } }
import cn.evchar.proxy.aop.RealSubject; import cn.evchar.proxy.aop.Subject; import java.lang.reflect.Proxy; public class Client { public static void main(String[] args) { System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true"); Subject subject = (Subject) Proxy.newProxyInstance(Client.class.getClassLoader(), new Class[]{Subject.class},new JdkProxySubject(new RealSubject())); subject.request(); subject.hello(); } }