您好,登錄后才能下訂單哦!
這篇文章主要講解了“Spring AOP核心類有哪些”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Spring AOP核心類有哪些”吧!
我們先來看下AnnotationAwareAspectJAutoProxyCreator類的結構圖。
上圖中一些 類/接口 的介紹:
AspectJAwareAdvisorAutoProxyCreator : 公開了AspectJ的調用上下文,并弄清楚來自同一切面的多個Advisor在AspectJ中的優先級規則。
AbstractAdvisorAutoProxyCreator : 通用自動代理創建器,它基于檢測到的每個顧問程序為特定bean構建AOP代理。
AbstractAutoProxyCreator : 擴展了 ProxyProcessorSupport,實現了SmartInstantiationAwareBeanPostProcessor、BeanFactoryAware 接口,是BeanPostProcessor 實現,該實現使用AOP代理包裝每個合格的bean,并在調用bean本身之前委派給指定的攔截器。
BeanFactoryAware : 實現了該接口的Bean可以知道它屬于那個 BeanFactory,Bean可以通過Spring容器查找它的協同者(依賴查找),但大多數的Bean是通過構造器參數和Bean方法(依賴注入)來獲取它的協同者。
BeanPostProcessor :工廠鉤子,允許自定義修改新的bean實例。例如,檢查標記接口或使用代理包裝bean。如果我們需要在Spring容器中完成Bean的實例化,配置和其初始化前后添加一些自己的邏輯處理,我們就可以定義一個或多個BeanPostProcessor接口的實現,然后注冊到容器中。
InstantiationAwareBeanPostProcessor : BeanPostProcessor 的子接口,它添加了實例化之前的回調,以及實例化之后但設置了顯式屬性或自動裝配之前的回調。它內部提供了3個方法,再加上BeanPostProcessor接口內部的2個方法,實現這個接口需要實現5個方法。InstantiationAwareBeanPostProcessor 接口的主要作用在于目標對象的實例化過程中需要處理的事情,包括實例化對象的前后過程以及實例的屬性設置。
SmartInstantiationAwareBeanPostProcessor : InstantiationAwareBeanPostProcessor 接口的擴展,多出了3個方法,添加了用于預測已處理bean的最終類型的回調,再加上父接口的5個方法,所以實現這個接口需要實現8個方法,主要作用也是在于目標對象的實例化過程中需要處理的事情。
總之:AspectJAwareAdvisorAutoProxyCreator為 AspectJ 切面類創建自動代理。
BeanPostProcessor 接口中的兩個方法 postProcessBeforeInitialization 和 postProcessAfterInitialization,作用是對Bean初始化前后添加一些自己的邏輯。
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
InstantiationAwareBeanPostProcessor 是 BeanPostProcessor 的子接口,它額外增加了3個新的方法:postProcessBeforeInstantiation( 目標對象被實例化之前調用的方法,可以返回目標實例的一個代理用來代替目標實例 )、postProcessAfterInstantiation(該方法在Bean實例化之后執行,返回false,會忽略屬性值的設置;如果返回true,會按照正常流程設置屬性值) 和 postProcessPropertyValues(對屬性值進行修改,未來版本將會刪除)
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
SmartInstantiationAwareBeanPostProcessor接口繼承InstantiationAwareBeanPostProcessor接口,里面定義了3個方法:predictBeanType(預測Bean的類型)、determineCandidateConstructors(選擇合適的構造器)、getEarlyBeanReference(解決循環引用問題)。
@Nullable
default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
@Nullable
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}
AbstractAutoProxyCreator 是AOP的一個核心類,它實現了SmartInstantiationAwareBeanPostProcessor、BeanFactoryAware 接口,實現了代理創建的邏輯,使用AOP代理包裝每個合格的bean,并在調用bean本身之前委派給指定的攔截器。
AbstractAdvisorAutoProxyCreator 通用自動代理創建器,它基于檢測每個bean的增強器,為特殊的bean構建AOP代理。子類可以重寫此findCandidateAdvisors()方法,以返回適用于任何對象的advisor的自定義列表,子類還可以重寫繼承的AbstractAutoProxyCreator.shouldSkip()方法,以將某些對象排除在自動代理之外。
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
return this.advisorRetrievalHelper.findAdvisorBeans();
}
AspectJAwareAdvisorAutoProxyCreator 擴展 AbstractAdvisorAutoProxyCreator,公開了AspectJ的調用上下文,并在多個增強器來自同一切面時搞清楚AspectJ的建議優先級順序。按AspectJ優先級排序其余部分:
@Override
@SuppressWarnings("unchecked")
protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
List<PartiallyComparableAdvisorHolder> partiallyComparableAdvisors = new ArrayList<>(advisors.size());
for (Advisor element : advisors) {
partiallyComparableAdvisors.add(
new PartiallyComparableAdvisorHolder(element, DEFAULT_PRECEDENCE_COMPARATOR));
}
List<PartiallyComparableAdvisorHolder> sorted = PartialOrder.sort(partiallyComparableAdvisors);
if (sorted != null) {
List<Advisor> result = new ArrayList<>(advisors.size());
for (PartiallyComparableAdvisorHolder pcAdvisor : sorted) {
result.add(pcAdvisor.getAdvisor());
}
return result;
}
else {
return super.sortAdvisors(advisors);
}
}
在增強鏈頭部增加一個ExposeInvocationInterceptor,使用AspectJ表達式切入點和使用AspectJ樣式的advisor時,需要這些附加advisor。
protected void extendAdvisors(List<Advisor> candidateAdvisors) {
AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
}
如果此后處理器不應該考慮將給定的bean用于自動代理,子類應重寫此方法以返回true
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// TODO: Consider optimization by caching the list of the aspect names
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
return super.shouldSkip(beanClass, beanName);
}
AspectJAwareAdvisorAutoProxyCreator 還有一個子類叫 AnnotationAwareAspectJAutoProxyCreator,子類AnnotationAwareAspectJAutoProxyCreator是用于處理當前應用程序上下文中的所有AspectJ注釋方面以及Spring Advisor。如果Spring AOP的基于代理的模型能夠應用任何AspectJ注釋的類,它們的advisor將被自動識別,這涵蓋了方法執行連接點,Spring Advisor的處理遵循AbstractAdvisorAutoProxyCreator中建立的規則。
從使用aop:xxx標簽來自動生成代理的話,先看看AopNamespaceHandler,使用aop:config標簽則使用 ConfigBeanDefinitionParser 解析,使用了aop:aspectj-autoproxy標簽則使用 AspectJAutoProxyBeanDefinitionParser 解析,依次類推。
@Override
public void init() {
// In 2.0 XSD as well as in 2.1 XSD.
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
// Only in 2.0 XSD: moved to context namespace as of 2.1
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}
ConfigBeanDefinitionParser.java
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
CompositeComponentDefinition compositeDef =
new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
parserContext.pushContainingComponent(compositeDef);
configureAutoProxyCreator(parserContext, element); // 注冊AspectJAwareAdvisorAutoProxyCreator
List<Element> childElts = DomUtils.getChildElements(element);
for (Element elt: childElts) {
String localName = parserContext.getDelegate().getLocalName(elt);
if (POINTCUT.equals(localName)) {
parsePointcut(elt, parserContext);
}
else if (ADVISOR.equals(localName)) {
parseAdvisor(elt, parserContext);
}
else if (ASPECT.equals(localName)) {
parseAspect(elt, parserContext);
}
}
parserContext.popAndRegisterContainingComponent();
return null;
}
private void configureAutoProxyCreator(ParserContext parserContext, Element element) {
AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element);
}
AopConfigUtils.java
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
CompositeComponentDefinition compositeDef =
new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
parserContext.pushContainingComponent(compositeDef);
configureAutoProxyCreator(parserContext, element); // 注冊AspectJAwareAdvisorAutoProxyCreator
List<Element> childElts = DomUtils.getChildElements(element);
for (Element elt: childElts) {
String localName = parserContext.getDelegate().getLocalName(elt);
if (POINTCUT.equals(localName)) {
parsePointcut(elt, parserContext);
}
else if (ADVISOR.equals(localName)) {
parseAdvisor(elt, parserContext);
}
else if (ASPECT.equals(localName)) {
parseAspect(elt, parserContext);
}
}
parserContext.popAndRegisterContainingComponent();
return null;
}
private void configureAutoProxyCreator(ParserContext parserContext, Element element) {
AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element);
}
AopConfigUtils.java
public static void registerAspectJAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
// 在這里注冊的是AspectJAwareAdvisorAutoProxyCreator
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
registerComponentIfNecessary(beanDefinition, parserContext); // 注冊組件
}
@Nullable
public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(AspectJAwareAdvisorAutoProxyCreator.class, registry, source);
}
AspectJAwareAdvisorAutoProxyCreator 實現了 BeanPostProcessor 等上面介紹的接口,主要作用于Bean初始化前后,實例化前后,所有的Bean都被作用到。InstantiationAwareBeanPostProcessor 是 BeanPostProcessor的子接口,但它的調用時間點發生在Bean實例化前,在真正調用doCreateBean()創建bean實例之前執行postProcessBeforeInstantiation()。
AbstractAutoProxyCreator.java
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName); // 得到一個緩存的唯一key(根據beanClass和beanName生成唯一key)
// 如果當前targetSourcedBeans(通過自定義TargetSourceCreator創建的TargetSource)不包含cacheKey
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) { //advisedBeans(已經被增強的Bean,即AOP代理對象)中包含當前cacheKey,返回null,即走Spring默認流程
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {// 如果是基礎設施類(如Advisor、Advice、AopInfrastructureBean的實現)不進行處理;(略)
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// 如果有自定義的TargetSource,在此處創建代理
// 禁止目標Bean的不必要的默認實例化:
// TargetSource將以自定義方式處理目標實例。
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
通過 AbstractAutoProxyCreator 中的 postProcessAfterInitialization() 創建AOP代理。
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) { // 如果之前調用過getEarlyBeanReference獲取包裝目標對象到AOP代理對象(如果需要),則不再執行
return wrapIfNecessary(bean, beanName, cacheKey); // 包裝目標對象到AOP代理對象(如果需要)
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { // 通過TargetSourceCreator進行自定義TargetSource不需要包裝
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { // 不應該被增強對象不需要包裝
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { // 基礎設施或應該skip的不需要保證
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 如果有advise則創建代理。
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); // 創建代理對象
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
感謝各位的閱讀,以上就是“Spring AOP核心類有哪些”的內容了,經過本文的學習后,相信大家對Spring AOP核心類有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。