【spring源碼學習】spring的AOP面向切面編程的實現解析
一:Advice(通知)
(1)定義在連接點做什麽,為切面增強提供織入接口。在spring aop中主要描述圍繞方法調用而註入的切面行為。
(2)spring定義了幾個時刻織入增強行為的接口
??=>org.springframework.aop.BeforeAdvice
???org.springframework.aop.MethodBeforeAdvice
??=>org.springframework.aop.AfterAdvice
???org.springframework.aop.AfterReturningAdvice
??=>org.springframework.aop.ThrowsAdvice
二:PointCut(切點)
(1)決定Advice應該作用那些連接點。也就是說通過PointCut來定義需要增強的方法集合。
(2)spring定義的PointCut的接口
??=>org.springframework.aop.Pointcut
??=>org.springframework.aop.TruePointcut
??=> org.springframework.aop.support.JdkRegexpMethodPointcut
(3)相關接口。PointCut接口會返回兩個對象,一個ClassFilter,一個是MethodMatcher
??=>org.springframework.aop.ClassFilter
??=>org.springframework.aop.TrueClassFilter
??=>org.springframework.aop.MethodMatcher 匹配當前方法是否需要執行增強邏輯,也就是是否需要執行Advice接口的方法。
??=>org.springframework.aop.TrueMethodMatcher
三:通知器皿(Advisor)
??(1)完成對目標方法的切面增強設計(advice)和關註點的設計(PoinCut)以後,需要一個對象把他們結合起來,完成這個作用的就是(Advisor)
??(2)spring定義的Advisor接口
??=>org.springframework.aop.Advisor
??=>org.springframework.aop.support.DefaultPointcutAdvisor
??(3)Advisor的控制器的接口
??=>org.springframework.aop.framework.adapter.AdvisorAdapter
??=>org.springframework.aop.framework.adapter.AfterReturningAdviceAdapter 目標方法執行完執行該增強的控制器
??=>org.springframework.aop.framework.adapter.MethodBeforeAdviceAdapter 目標方法未執行前執行該增強的控制器
??=>org.springframework.aop.framework.adapter.ThrowsAdviceAdapter 目標方法執行過程拋出異常執行該增強的控制器
四:springAop的相關
??(1)springAop的核心技術是動態代理。動態代理的技術是jdk的一個特征。
??(2)springAop的代理對象生成案例
????=>org.springframework.aop.framework.ProxyFactoryBean
????=>org.springframework.aop.framework.ProxyFactory
五:ProxyFactoryBean的工作流程。
(1)實現FactoryBean接口的類,在想IOC容器申請bean的時候,其實返回的是該類執行getObject()方法的返回。
(2)ProxyFactoryBean的getObject()方法返回的是目標對象的代理對象。
??其執行過程
??=>根據配置的interceptorNames的屬性值先初始化代理增強的鏈子.根據interceptorNames從IOC容器中得到增強類的bean,然後判斷其類型,形成DefaultPointcutAdvisor對象。
??=>根據配置的targetName屬性值從IOC容器中得到目標對象的bean,形成一個SingletonTargetSource對象。
??=>將其本身作為一個aop代理對象創建的數據配置類,創建一個動態代理對象,返回給ioc容器申請。
(3)在執行目標對象的方法過程中,會根據執行的方法的對象,從代理鏈子裏找到所有的Advisor對象,然後利用其屬性Pointcut對象獲取ClassFilter, MethodMatcher來判斷當前Advisor是否要執行。如果執行,則加入執行代理鏈子中。以jdk動態代理為例子,是org.springframework.aop.framework.JdkDynamicAopProxy類中invoke(Object proxy, Method method, Object[] args)方法中這句代碼List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);。該句代碼中this.advised其實就是ProxyFactoryBean本身。
六案例
一:Advice的對象
package com.mobile.thinks.aop.advice; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; public class LoginBeforeAdvice implements MethodBeforeAdvice{ @Override public void before(Method method, Object[] args, Object target)throws Throwable { System.out.println(View Code"LoginBeforeAdvice.before()執行方法為==>"+method.getName()); System.out.println("LoginBeforeAdvice.before()執行參數為==>"+args); System.out.println("LoginBeforeAdvice.before()執行的目標為==>"+target.getClass()); } }
二:目標對象
package com.mobile.thinks.service.impl;View Codeimport java.util.Date; import org.springframework.stereotype.Service; import com.mobile.thinks.entity.User; import com.mobile.thinks.service.UserInfoService; @Service(value="userInfoServiceImpl") public class UserInfoServiceImpl implements UserInfoService{ @Override public User loginByUserNameAndPassWord(String userName, String passWord) { User user=new User(); user.setAddress("三門峽"); user.setAge(28); user.setCreateTime(new Date()); user.setName(userName); return user; } }
三:配置文件
<!-- 測試ProxyFactoryBean --> <!--定義一個advice --> <bean name="loginBeforeAdvice" class="com.mobile.thinks.aop.advice.LoginBeforeAdvice" /> <!-- 定義FactoryBean --> <bean name="userInfoService" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 要代理的目標對象,在ioc容器中的名字 --> <property name="targetName"> <value>userInfoServiceImpl</value> </property> <!-- 要植入增強功能的advice在IOC容器中的名字 --> <property name="interceptorNames"> <list><value>loginBeforeAdvice</value></list> </property> </bean>View Code
七:spring內部基於該中方式實現動態代理的案例。spring提供的HttpInvoker遠程調用.可以閱讀該類getObject方法。實現對Facade接口代理
org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean
【spring源碼學習】spring的AOP面向切面編程的實現解析