面向切面編程,是一種編程範式,提供從另外一個角度來考慮程序結構從而完善面向對象編程(OOP)。java
在進行OOP開發時,都是基於對組件(好比類)進行開發,而後對組件進行組合,OOP最大問題就是沒法解耦組件進行開發。spring
AOP爲開發者提供一種進行橫切關注點(好比日誌關注點橫切了支付關注點)分離並織入的機制,把橫切關注點分離,而後經過某種技術織入到系統中,從而無耦合的完成了咱們的功能。編程
橫切關注點可能包含不少,好比非業務的:日誌、事務處理、緩存、性能統計、權限控制等;還多是業務的:如某個業務組件橫切於多個模塊。數組
What-@Aspect緩存
Where-@Pointcutapp
When-@Advice(@Before、@After、@AfterReturning、@AfterThrowing、@Around)框架
在Spring中經過代理模式實現AOP,並經過攔截器模式以環繞鏈接點的攔截器鏈織入通知(即應用切面)jvm
Spring中能夠經過在切面實現類上實現org.springframework.core.Ordered接口或使用Order註解來指定切面優先級。在多個切面中,Ordered.getValue()方法返回值(或者註解值)較小值的那個切面擁有較高優先級。ide
@Order(2)
若是目標對象實現了接口,默認使用JDK,能夠強制用CGLIB;不然,採用CGLIB。模塊化
只能爲接口建立動態代理實例,而不能針對類。
使用java.lang.reflect.Proxy動態代理實現,經過調用目標類的getClass().getInterfaces()方法獲取目標對象的接口信息,並生成一個實現了代理接口的動態代理class,而後經過反射技術得到該class的構造函數,並利用構造函數生成實例,在調用具體方法前調用InvocationHandler處理。
在Proxy這個類當中首先實例化一個對象ProxyClassFactory,而後在get方法中調用了apply方法,完成對代理類的建立:
主要是對指定的類生成一個子類,覆蓋其中的方法。(不能通知final方法)
利用asm開源包,採用字節碼技術,爲一個類建立子類,在子類中採用方法攔截(MethodInterceptor @override intercept()),攔截全部父類方法的調用,順勢織入橫切邏輯。
會產生兩次構造器調用,第一次是目標類的構造器調用,第二次是CGLIB生成的代理類的構造器調用。
在依賴注入時,實例化bean後都會調用getObjectForBeanInstance方法,這裏就是處理FactoryBean的入口。
經過配置和調用ProxyFactoryBean來完成代理對象的建立。
配置通知器advisor、proxyFactoryBean(目標對象target、interceptorNames攔截器數組、目標對象接口數組)
// ProxyFactoryBean @Nullable public Object getObject() throws BeansException { // 對通知器鏈進行初始化 // 通知器鏈封裝了一系列的攔截器(須要從配置中讀取) // 而後爲代理對象的生成作準備 this.initializeAdvisorChain(); // 區分兩種類型的Bean if (this.isSingleton()) { return this.getSingletonInstance(); } else { ... return this.newPrototypeInstance(); } } private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException { // 通知器鏈未初始化(初始化工做發生在應用第一次經過ProxyFactoryBean獲取代理對象的時候) if (!this.advisorChainInitialized) { if (!ObjectUtils.isEmpty(this.interceptorNames)) { ... String[] var1 = this.interceptorNames; int var2 = var1.length; for(int var3 = 0; var3 < var2; ++var3) { String name = var1[var3]; ... if (name.endsWith("*")) { ... } else { Object advice; if (!this.singleton && !this.beanFactory.isSingleton(name)) { // Prototype類型 advice = new ProxyFactoryBean.PrototypePlaceholderAdvisor(name); } else { // singleton類型:經過getBean獲取通知器 advice = this.beanFactory.getBean(name); } // 將通知器加入攔截器鏈中 this.addAdvisorOnChainCreation(advice, name); } } } this.advisorChainInitialized = true; } } private synchronized Object getSingletonInstance() { if (this.singletonInstance == null) { this.targetSource = this.freshTargetSource(); if (this.autodetectInterfaces && this.getProxiedInterfaces().length == 0 && !this.isProxyTargetClass()) { // 判斷須要代理的接口 Class<?> targetClass = this.getTargetClass(); ... // 設置代理對象調用接口 this.setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader)); } super.setFrozen(this.freezeProxy); // createAopProxy:生成aop代理對象 ★調用父類的createAopProxy() // getProxy:<<AopProxy>>接口的兩種實現--JdkDynamicAopProxy、CglibAopProxy this.singletonInstance = this.getProxy(this.createAopProxy()); } return this.singletonInstance; } private synchronized Object newPrototypeInstance() { ... ProxyCreatorSupport copy = new ProxyCreatorSupport(this.getAopProxyFactory()); TargetSource targetSource = this.freshTargetSource(); copy.copyConfigurationFrom(this, targetSource, this.freshAdvisorChain()); if (this.autodetectInterfaces && this.getProxiedInterfaces().length == 0 && !this.isProxyTargetClass()) { // 和上面如出一轍的套路啊。。。 Class<?> targetClass = targetSource.getTargetClass(); if (targetClass != null) { copy.setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader)); } } ... // 而後經過<<AopProxy>>接口的兩種實現--JdkDynamicAopProxy、CglibAopProxy獲取代理對象 return this.getProxy(copy.createAopProxy()); }
// ProxyCreatorSupport protected final synchronized AopProxy createAopProxy() { if (!this.active) { this.activate(); } // createAopProxy:<<AopProxyFactory>>接口的方法 return this.getAopProxyFactory().createAopProxy(this); }
// 具體實現:DefaultAopProxyFactory public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { // 若是目標對象是接口類,使用jdk if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) { return new JdkDynamicAopProxy(config); } else { Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { ... } else { // ObjenesisCglibAopProxy extends CglibAopProxy return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config)); } } // new的過程都是先從AdvisedSupport對象中取得配置的目標對象進行檢查 }
// JdkDynamicAopProxy public Object getProxy(@Nullable ClassLoader classLoader) { ... // 首先從advised對象中獲取代理對象的代理接口配置 Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true); this.findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); // 而後調用Proxy的newProxyInstance方法獲得Proxy代理對象 // 須要三個參數:類加載器、代理接口、回調方法所在對象 // 回調方法用的是InvokeHandler的invoke回調入口 return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); }
// CglibAopProxy public Object getProxy(@Nullable ClassLoader classLoader) { ... try { // 從advised對象中獲取配置的target對象 Class<?> rootClass = this.advised.getTargetClass(); ... Class<?> proxySuperClass = rootClass; int x; if (ClassUtils.isCglibProxyClass(rootClass)) { proxySuperClass = rootClass.getSuperclass(); Class<?>[] additionalInterfaces = rootClass.getInterfaces(); Class[] var5 = additionalInterfaces; int var6 = additionalInterfaces.length; for(x = 0; x < var6; ++x) { Class<?> additionalInterface = var5[x]; this.advised.addInterface(additionalInterface); } } // 驗證代理對象的接口設置 this.validateClassIfNecessary(proxySuperClass, classLoader); // 建立並配置cglib的enhancer Enhancer enhancer = this.createEnhancer(); if (classLoader != null) { enhancer.setClassLoader(classLoader); if (classLoader instanceof SmartClassLoader && ((SmartClassLoader)classLoader).isClassReloadable(proxySuperClass)) { enhancer.setUseCache(false); } } // 設置enhancer的代理接口、回調方法等 enhancer.setSuperclass(proxySuperClass); enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised)); enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE); enhancer.setStrategy(new CglibAopProxy.ClassLoaderAwareUndeclaredThrowableStrategy(classLoader)); Callback[] callbacks = this.getCallbacks(rootClass); Class<?>[] types = new Class[callbacks.length]; for(x = 0; x < types.length; ++x) { types[x] = callbacks[x].getClass(); } enhancer.setCallbackFilter(new CglibAopProxy.ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset)); enhancer.setCallbackTypes(types); // 經過enhancer生成代理對象 ★ // 注意這裏有回調 return this.createProxyClassAndInstance(enhancer, callbacks); }... } // 這裏是回調方法,經過設置DynamicAdvisedInterceptor攔截器完成AOP功能 private Callback[] getCallbacks(Class<?> rootClass) throws Exception { ... Callback aopInterceptor = new CglibAopProxy.DynamicAdvisedInterceptor(this.advised); ... return callbacks; }
在第一步的過程當中,攔截器已經配置到代理對象中,它是經過回調方法起做用。
@Nullable public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object oldProxy = null; boolean setProxyContext = false; TargetSource targetSource = this.advised.targetSource; Object target = null; Boolean var8; try { if (this.equalsDefined || !AopUtils.isEqualsMethod(method)) { ... // 獲得目標對象 target = targetSource.getTarget(); Class<?> targetClass = target != null ? target.getClass() : null; // 這個方法對象註冊了攔截器 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); // 沒有設定攔截器鏈,直接調用target對象的方法 if (chain.isEmpty()) { Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); // 對target對象的方法調用是經過反射機制,而後使用invoke調用方法反射對象 retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse); } else { // 攔截,經過ReflectiveMethodInvocation MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); // 沿着攔截器鏈繼續前進 retVal = invocation.proceed(); } ... } var8 = this.equals(args[0]); }... return var8; }
@Nullable public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { ... try { ... // 獲得目標對象 target = targetSource.getTarget(); Class<?> targetClass = target != null ? target.getClass() : null; // 從advised取得配置好的AOP通知 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); Object retVal; // 若沒有,則直接調用target對象的方法 if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) { Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); retVal = methodProxy.invoke(target, argsToUse); } else { // 攔截,經過CglibMethodInvocation啓動advice通知 // CglibMethodInvocation extends ReflectiveMethodInvocation // 沿着攔截器鏈繼續前進 retVal = (new CglibAopProxy.CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)).proceed(); } retVal = CglibAopProxy.processReturnType(proxy, target, method, retVal); var16 = retVal; }... return var16; }
綜上,都是從advised取得攔截器鏈的。
攔截都是經過ReflectiveMethodInvocation的proceed方法實現的。
攔截器是ReflectiveMethodInvocation類中一個名爲interceptorsAndDynamicMethodMatchers的List中的元素。
this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
advised的getInterceptorsAndDynamicInterceptionAdvice是由advisorChainFactory實現的,它的具體類型是DefaultAdvisorChainFactory。
DefaultAdvisorChainFactory經過AdvisorAdapterRegistry來適配ProxyFactoryBean中獲得的通知器,註冊攔截器。
在ProxyFactoryBean的getObject方法中對advisor進行初始化時,從配置中獲取了通知器。(經過實現BeanFactoryAware接口,設置回調方法委託給IoC容器)
@Nullable public Object proceed() throws Throwable { // 若是已經到攔截器鏈的末尾,直接調用目標對象的方法 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return this.invokeJoinpoint(); } else { // 不然,獲得下一個攔截器 Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); // 經過攔截器進行matches判斷是否適用於橫切加強的場合 if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice; Class<?> targetClass = this.targetClass != null ? this.targetClass : this.method.getDeclaringClass(); // 若是是,從攔截器獲得通知器,並啓動invoke方法 // 不然,迭代調用proceed方法 return dm.methodMatcher.matches(this.method, targetClass, this.arguments) ? dm.interceptor.invoke(this) : this.proceed(); } else { return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this); } } }
DefaultAdvisorChainFactory經過AdvisorAdapterRegistry來適配ProxyFactoryBean中獲得的通知器,註冊攔截器。
// DefaultAdvisorChainFactory public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, @Nullable Class<?> targetClass) { // GlobalAdvisorAdapterRegistry是一個單例,做用是適配器 AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance(); Advisor[] advisors = config.getAdvisors(); ... for(int var11 = 0; var11 < var10; ++var11) { Advisor advisor = var9[var11]; if (advisor instanceof PointcutAdvisor) { PointcutAdvisor pointcutAdvisor = (PointcutAdvisor)advisor; if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) { ... if (match) { MethodInterceptor[] interceptors = registry.getInterceptors(advisor); ... } } } else if (advisor instanceof IntroductionAdvisor) { IntroductionAdvisor ia = (IntroductionAdvisor)advisor; if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) { Interceptor[] interceptors = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(interceptors)); } } else { Interceptor[] interceptors = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(interceptors)); } } return interceptorList; }
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
封裝着advice織入實現的入口。
// DefaultAdvisorAdapterRegistry public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException { List<MethodInterceptor> interceptors = new ArrayList(3); Advice advice = advisor.getAdvice(); if (advice instanceof MethodInterceptor) { interceptors.add((MethodInterceptor)advice); } // 對通知進行適配 Iterator var4 = this.adapters.iterator(); while(var4.hasNext()) { AdvisorAdapter adapter = (AdvisorAdapter)var4.next(); // 若是適配器支持某種通知,則從對應的適配器中獲取該類通知器的攔截器 if (adapter.supportsAdvice(advice)) { interceptors.add(adapter.getInterceptor(advisor)); } } ... }
咱們知道,proceed處理攔截器的時候是經過dm.interceptor.invoke(this)
攔截器的回調方法。下面舉一個例子。
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable { MethodBeforeAdviceAdapter() { } public boolean supportsAdvice(Advice advice) { return advice instanceof MethodBeforeAdvice; } public MethodInterceptor getInterceptor(Advisor advisor) { MethodBeforeAdvice advice = (MethodBeforeAdvice)advisor.getAdvice(); return new MethodBeforeAdviceInterceptor(advice); } }
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable { private final MethodBeforeAdvice advice; public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; } // 先觸發advice的before,而後纔是proceed調用! // 由於這是method before!若是是其餘的攔截器,順序、具體實現又不同了 public Object invoke(MethodInvocation mi) throws Throwable { this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis()); return mi.proceed(); } }