目錄
配置類
AopAutoConfiguration
AspectJAutoProxyingConfiguration
ClassProxyingConfiguration
@EnableAspectJAutoProxy
AspectJAutoProxyRegistrar
AopConfigUtils
代理生成
AnnotationAwareAspectJAutoProxyCreator
Aware
BeanPostProcessor
AopInfrastructureBean
ProxyConfig
ProxyProcessorSupport
AbstractAutoProxyCreator
屬性
Aware實作
BeanPostProcessor實作
InstantiationAwareBeanPostProcessor實作
SmartInstantiationAwareBeanPostProcessor實作
wrapIfNecessary
createProxy
buildAdvisors
AbstractAdvisorAutoProxyCreator
BeanFactoryAdvisorRetrievalHelper
AspectJAwareAdvisorAutoProxyCreator
extendAdvisors
AspectJProxyUtils
AnnotationAwareAspectJAutoProxyCreator
覆寫父類:findCandidateAdvisors
BeanFactoryAspectJAdvisorsBuilder
DefaultAdvisorAutoProxyCreator
InfrastructureAdvisorAutoProxyCreator
AOP是怎麼生效的呢?在spring boot項目spring-boot-autoconfigure中spring.factories檔案配置了自動導入:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
... ...
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
配置類
AopAutoConfiguration
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {
}
當配置spring.aop.auto=true時(true為預設值),則導入配置。AopAutoConfiguration 内部又定義了2個配置類。
AspectJAutoProxyingConfiguration
AspectJAutoProxyingConfiguration 在定義了Advice才會導入。并且實作了2種可替換模式:JDK動态代理和cglib代理。通過spring.aop.proxy-target-class屬性控制。如果沒有指定,則2種模式互相配置,有接口的用動态代理,沒有接口用cglib,如果指定了值,則使用指定了的方式代理對象。
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Advice.class)
static class AspectJAutoProxyingConfiguration {
@Configuration(proxyBeanMethods = false)
@EnableAspectJAutoProxy(proxyTargetClass = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",
matchIfMissing = false)
static class JdkDynamicAutoProxyConfiguration {
}
@Configuration(proxyBeanMethods = false)
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
matchIfMissing = true)
static class CglibAutoProxyConfiguration {
}
}
ClassProxyingConfiguration
配置使用cglib動态代理的情況下,如果沒有引入org.aspectj.weaver.Advice時的代理方式。
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingClass("org.aspectj.weaver.Advice")
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
matchIfMissing = true)
static class ClassProxyingConfiguration {
ClassProxyingConfiguration(BeanFactory beanFactory) {
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
}
}
@EnableAspectJAutoProxy
導入了AspectJAutoProxyRegistrar。用于注冊自動生成代理。
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
/**是否采用cglib方式*/
boolean proxyTargetClass() default false;
/**是否ThreadLocal 類型。
* @since 4.3.1
*/
boolean exposeProxy() default false;
}
AspectJAutoProxyRegistrar
AspectJAutoProxyRegistrar用于注冊AutoProxy。第1部分将AnnotationAwareAspectJAutoProxyCreator類型包裝成BeanDefinition注冊到Spring容器。第2部分将proxyTargetClass的配置設定到此BeanDefinition裡。
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//1
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
//2
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
AopConfigUtils
AOP auto-proxy creator 注冊處理工具類。注冊了3個creator。一般BeanDefinition采用的最後一個creator:AnnotationAwareAspectJAutoProxyCreator。
private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<>(3);
//使用數組,用來排序,最後一個的優先級最高。
static {
// Set up the escalation list...
APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
}
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//AUTO_PROXY_CREATOR_BEAN_NAME = "org.springframework.aop.config.internalAutoProxyCreator";
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
//類型不比對,則根據優先級确定設定哪個creator。
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
//注冊beandefinition。
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
代理生成
AnnotationAwareAspectJAutoProxyCreator
AnnotationAwareAspectJAutoProxyCreator,其繼承關系如下:
Aware
可以設定ClassLoader,以及BeanFactory。
public interface BeanClassLoaderAware extends Aware {
void setBeanClassLoader(ClassLoader classLoader);
}
public interface BeanFactoryAware extends Aware {
void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}
BeanPostProcessor
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
@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 postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
return null;
}
@Deprecated
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
//傳回bean最終的類型。用于提前給出postProcessBeforeInstantiation生成的bean的類型
@Nullable
default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
//傳回bean的可選構造函數清單。用于bean初始化的時候決定調用哪一個構造函數,如果針對某個類型的bean設定了這個回調,會采用回調設定的構造函數初始化bean
@Nullable
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
throws BeansException {
return null;
}
//用于解決循環依賴的問題
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}
}
AopInfrastructureBean
一個标記接口。
public interface AopInfrastructureBean {
}
ProxyConfig
ProxyConfig是所有産生Spring AOP代理對象的基類,它是一個資料類,主要為其AOP代理對象工廠實作類提供基本的配置屬性。
public class ProxyConfig implements Serializable {
private static final long serialVersionUID = -8409359707199703185L;
// 如果該值為true,則proxyFactory将會使用CGLIB對目标對象進行代理,預設值為false
private boolean proxyTargetClass = false;
// 标記是否對代理進行優化。啟動優化通常意味着在代理對象被建立後,增強的修改将不會生效(即增強僅對修改之後的代理對象起作用,對修改前的修改不起作用),是以預設值為false。
private boolean optimize = false;
// 該屬性用于空值生成的代理對象是否可以強制轉型為Advised,預設值為false,表示任何生成的代理對象都可以強制轉換成Advised,true是不可以,可以通過Adviced查詢代理對象的一些狀态
//[əʊˈpeɪk],不透明的;不傳熱的;遲鈍的
boolean opaque = false;
// 标記代理對象是否應該被aop架構通過AopContext以ThreadLocal的形式暴露出去。
// 當一個代理對象需要調用它自己的另外一個代理方法時,這個屬性将非常有用。預設是是false,以避免不必要的攔截。
//即在方法内部互相調用時,通過((Target)AopContext.currentProxy()).innerCall(); 擷取增強後目前代理對象。
boolean exposeProxy = false;
// 标記該配置是否需要被當機,如果被當機,将不可以修改增強的配置。
// 如果該值為true,那麼代理對象的生成的各項資訊配置完成,則不容許更改,如果ProxyFactory設定完畢,該值為true,則不能對Advice進行改動,可以優化代理對象生成的性能。預設情況下該值為false
private boolean frozen = false;
...
}
ProxyProcessorSupport
建立代理支援類。主要功能是:檢測代理類是否有使用者接口(包括代理類本身),如果有則proxyTargetClass為false,否則proxyTargetClass為true。即如果有接口,則使用JDK動态代理,否則使用cglib代理。
AOP的自動代理建立器必須在所有的别的processors之後執行,以確定它可以代理到所有的小夥伴們,即使需要雙重代理的那種。是以Order設定為最低優先級。
//判斷是InitializingBean,DisposableBean這些配置回調接口
protected boolean isConfigurationCallbackInterface(Class<?> ifc) {
return (InitializingBean.class == ifc || DisposableBean.class == ifc || Closeable.class == ifc ||
AutoCloseable.class == ifc || ObjectUtils.containsElement(ifc.getInterfaces(), Aware.class));
}
//内部語言接口
protected boolean isInternalLanguageInterface(Class<?> ifc) {
return (ifc.getName().equals("groovy.lang.GroovyObject") ||
ifc.getName().endsWith(".cglib.proxy.Factory") ||
ifc.getName().endsWith(".bytebuddy.MockAccess"));
}
protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
boolean hasReasonableProxyInterface = false;
for (Class<?> ifc : targetInterfaces) {
if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
ifc.getMethods().length > 0) {
hasReasonableProxyInterface = true;
break;
}
}
if (hasReasonableProxyInterface) {
// Must allow for introductions; can't just set interfaces to the target's interfaces only.
for (Class<?> ifc : targetInterfaces) {
proxyFactory.addInterface(ifc);
}
}
else {
proxyFactory.setProxyTargetClass(true);
}
}
AbstractAutoProxyCreator
這個類是這個繼承鍊中最核心的類,因為生成代理的邏輯封裝在這裡,它實作SmartInstantiationAwareBeanPostProcessor,在回調方法裡封裝了把bean對象替換為代理對象的邏輯,在getEarlyBeanReference,postProcessBeforeInstantiation, postProcessAfterInitialization均能産生代理,postProcessBeforeInstantiation需要在配置了TargetSourceCreator之後才能生效。getEarlyBeanReference是為了解決循環依賴重寫的,用來提前産生代理類,postProcessAfterInitialization在getEarlyBeanReference沒有生效的情況下會被調用,這兩個方法都調用了wrapIfNecessary來生成代理
屬性
/*不代理時傳回對象:null*/
@Nullable
protected static final Object[] DO_NOT_PROXY = null;
/*沒有任何增強接口對象:object*/
protected static final Object[] PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS = new Object[0];
/** AdvisorAdapterRegistry,預設是GlobalAdvisorAdapterRegistry. */
private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
/**訓示代理對象是否應該當機*/
private boolean freezeProxy = false;
/**攔截器名稱清單. */
private String[] interceptorNames = new String[0];
private boolean applyCommonInterceptorsFirst = true;
@Nullable
private TargetSourceCreator[] customTargetSourceCreators;
@Nullable
private BeanFactory beanFactory;
private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
private final Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap<>(16);
private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<>(16);
private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256);
Aware實作
BeanPostProcessor實作
初始化前不做處理,初始化後如果有必要則包裝。
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
InstantiationAwareBeanPostProcessor實作
/**
* 在建立Bean的流程中還沒調用構造器來執行個體化Bean的時候進行調用(執行個體化前後)
* AOP解析切面以及事務解析事務注解都是在這裡完成的
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
//擷取BeanClass的緩存key
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
//advisedBeans儲存了所有已經做過動态代理的Bean
// 如果被解析過則直接傳回
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
// 1. 判斷目前bean是否是基礎類型:是否實作了Advice,Pointcut,Advisor,AopInfrastructureBean這些接口或是否是切面(@Aspect注解)
// 2. 判斷是不是應該跳過 (AOP解析直接解析出我們的切面資訊,
// 而事務在這裡是不會解析的)
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
//擷取使用者自定義的targetSource, 如果存在則直接在對象執行個體化之前進行代理建立,
// 避免了目标對象不必要的執行個體化
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
//如果有自定義targetSource就要這裡建立代理對象
//這樣做的好處是被代理的對象可以動态改變,而不是值針對一個target對象(可以對對象池中對象進行代理,可以每次建立代理都建立新對象
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
//擷取Advisors, 這個是交給子類實作的
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
//傳回代理的對象
return proxy;
}
return null;
}
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) {
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
return pvs;
}
SmartInstantiationAwareBeanPostProcessor實作
wrapIfNecessary
wrapIfNecessary首先會通過getAdvicesAndAdvisorsForBean得到攔截器集合,這個會交給子類實作,子類可以設計不同的政策來擷取攔截器集合,如果getAdvicesAndAdvisorsForBean傳回的集合不為空,就調用createProxy生成代理
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//已經有bean,直接傳回。
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//沒有advice,直接傳回bean。
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
//不需要處理的,直接傳回。
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 如果有advice,則進行代理。由子類實作
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;
}
createProxy
使用了ProxyFactory的程式設計式Aop生成代理。
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
//建立代理工廠
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
//JDK還是cglib判斷。
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//構造Advisor。
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//傳回代理對象。
return proxyFactory.getProxy(getProxyClassLoader());
}
buildAdvisors
此函數把攔截器包裝成Advisor,是通過AdvisorAdapterRegistry類來完成。
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
// Handle prototypes correctly...
//指定攔截器name 處理成Advisor。
Advisor[] commonInterceptors = resolveInterceptorNames();
//所有攔截器
List<Object> allInterceptors = new ArrayList<>();
if (specificInterceptors != null) {
//
allInterceptors.addAll(Arrays.asList(specificInterceptors));
if (commonInterceptors.length > 0) {
if (this.applyCommonInterceptorsFirst) {
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
}
else {
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
}
}
if (logger.isTraceEnabled()) {
int nrOfCommonInterceptors = commonInterceptors.length;
int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
logger.trace("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +
" common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");
}
//Advisor:攔截器包裝成Advisor。
Advisor[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}
AdvisorAdapterRegistry
AdvisorAdapterRegistry 實作攔截器包裝成Advisor功能,以及注冊AdvisorAdapter 。AdvisorAdapterRegistry通過GlobalAdvisorAdapterRegistry擷取單例:DefaultAdvisorAdapterRegistry執行個體。
public interface AdvisorAdapterRegistry {
Advisor wrap(Object advice) throws UnknownAdviceTypeException;
MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException;
void registerAdvisorAdapter(AdvisorAdapter adapter);
}
private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
DefaultAdvisorAdapterRegistry
DefaultAdvisorAdapterRegistry預設注冊3個AdvisorAdapter。wrap方法把攔截器包裝成DefaultPointcutAdvisor。DefaultPointcutAdvisor比對任何方法。
public DefaultAdvisorAdapterRegistry() {
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
ProxyFactory
ProxyFactory是真正建立代理對象的工廠。内容太多,放後面再分析。
AbstractAdvisorAutoProxyCreator
AbstractAdivisorAutoProxyCreator主要實作了AbstractAutoProxyCreator提供的擴充點方法getAdvicesAndAdvisorsForBean,用來設定攔截器集合。通過BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans()擷取Advisors。
1、findCandidateAdvisors()方法先擷取注冊到Spring容器中的Advisor。
2、findAdvisorsThatCanApply()過濾Advisor,Advisor(切點)包含了Pointcut(切點)和Advice(增強),findAdvisorsThatCanApply方法的過濾就是利用Advisor中Pointcut比對Class或Method來達到過濾的目的。
3、extendAdvisors()擴充Adviors,由子類實作。
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//1.
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//2.
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
//3.
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
return this.advisorRetrievalHelper.findAdvisorBeans();
}
BeanFactoryAdvisorRetrievalHelper
從容器中擷取
Spring
Advisor
bean
: 也就是實作了接口
org.springframework.aop.Advisor
的
bean
。
public List<Advisor> findAdvisorBeans() {
//擷取Advisor的name
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
//查找Advisor.class類型的bean的name。不要在此處初始化FactoryBeans,讓auto-proxy creator處理。
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
if (advisorNames.length == 0) {
return new ArrayList<>();
}
List<Advisor> advisors = new ArrayList<>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
//擷取Advisor
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
... ...
}
}
}
}
return advisors;
}
AspectJAwareAdvisorAutoProxyCreator
Aspectj的實作方式,也是Spring Aop中最常用的實作方式,如果用注解方式,則用其子類
AnnotationAwareAspectJAutoProxyCreator
。
重寫了父類的extendAdvisors()。作用就是在所有的advisors節點最前面插入一個Advisor(有advisors節點前提下,DefaultPointcutAdvisor),此Advisor比較特殊它的Pointcut是全類型比對的(比對所有Class和Method),它主要功能是在于它的Advice(增強),它的Advice實作是ExposeInvocationInterceptor類,看類的名稱就知道,對外暴露的類,就是所有Advice調用鍊的第一環,ExposeInvocationInterceptor作用就是将調用資訊存在ThreadLocal實作的上下文資訊裡,供調用鍊後續的Advice擷取使用。
extendAdvisors
@Override
protected void extendAdvisors(List<Advisor> candidateAdvisors) {
AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
}
AspectJProxyUtils
AspectJ代理工具類。
private static boolean isAspectJAdvice(Advisor advisor) {
return (advisor instanceof InstantiationModelAwarePointcutAdvisor ||
advisor.getAdvice() instanceof AbstractAspectJAdvice ||
(advisor instanceof PointcutAdvisor &&
((PointcutAdvisor) advisor).getPointcut() instanceof AspectJExpressionPointcut));
}
public static boolean makeAdvisorChainAspectJCapableIfNecessary(List<Advisor> advisors) {
// Don't add advisors to an empty list; may indicate that proxying is just not required
if (!advisors.isEmpty()) {
boolean foundAspectJAdvice = false;
for (Advisor advisor : advisors) {
// Be careful not to get the Advice without a guard, as this might eagerly
// instantiate a non-singleton AspectJ aspect...
if (isAspectJAdvice(advisor)) {
foundAspectJAdvice = true;
break;
}
}
if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) {
advisors.add(0, ExposeInvocationInterceptor.ADVISOR);
return true;
}
}
return false;
}
public static final Advisor ADVISOR = new DefaultPointcutAdvisor(INSTANCE) {
@Override
public String toString() {
return ExposeInvocationInterceptor.class.getName() +".ADVISOR";
}
};
AnnotationAwareAspectJAutoProxyCreator
AnnotationAwareAspectJAutoProxyCreator
AnnotationAwareAspectJAutoProxyCreator
:目前最常用的AOP使用方式。spring aop 開啟注解方式之後,該類會掃描所有
@Aspect()
注釋的類,生成對應的
adviosr
。目前
SpringBoot
架構中預設支援的方式,自動配置。
通過BeanFactoryAspectJAdvisorsBuilder建立AspectJ Advisor。
覆寫父類:findCandidateAdvisors
@Override
protected List<Advisor> findCandidateAdvisors() {
List<Advisor> advisors = super.findCandidateAdvisors();
// 利用了aspectj來解析注解了@Aspect
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
BeanFactoryAspectJAdvisorsBuilder
BeanFactoryAspectJAdvisorsBuilder
是一個
Spring AOP
内部工具類,該工具類用來從
bean
容器,也就是
BeanFactory
中擷取所有使用了
@AspectJ
注解的
bean
,最終用于自動代理機制(
auto-proxying
)。
buildAspectJAdvisors() 方法将所有 @AspectJ bean advice 方法包裝成Spring Advisor清單傳回:
1. 從容器中找到所有@AspectJ注解的bean;
2. 将找到的每個@AspectJ bean的每個advice方法封裝成一個Spring Advisor;
3. 緩存找到的Spring Advisor;
4. 将上述找到的所有Spring Advisor組織成一個清單傳回
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
//線程安全處理。二次check 方法
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
// 擷取所有類型為Object的bean的名稱,基本上也就是說所有的bean的名稱了
// includeNonSingletons:true=>包含單例,非單例bean
// allowEagerInit:false=>不要初始化lazy-init singletons和FactoryBean建立的bean
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
// 本執行個體自己提供的篩查條件,預設實作總是傳回true,
// 子類可以覆寫該方法提供自己的實作
continue;
}
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
// 檢測該bean是否使用了注解@AspectJ
if (this.advisorFactory.isAspect(beanType)) {
// 檢測到了一個使用注解@AspectJ的bean
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
// 切面的屬性為單例模式
if (amd.getAjType().getPerClause().getKind() ==
PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory,
beanName);
// 從@AspectJ注解的類,也就是AspectJ切面類中分析
// 其advice方法,每個構造成一個Spring Advisor,
// pointcut 資訊 和 advice 資訊已經包含在相應的Advisor
// 對象中
List<Advisor> classAdvisors =
this.advisorFactory.getAdvisors(factory);
// 單例模式,隻需要将生成的Advisor添加到緩存
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
// 多執行個體模式,需要儲存工廠類,便于下一次再次生成Advisor執行個體。
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
// 非單例模式,每個執行個體處理一次。
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" +
beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
//如果緩存中有,則從緩存中取。
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
List<Advisor> advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
AspectJAdvisorFactory
為AspectJ的切面構造Advisor,也就是說處理@Aspect修飾的類。構造器預設使用的是ReflectiveAspectJAdvisorFactory。
public interface AspectJAdvisorFactory {
boolean isAspect(Class<?> clazz);
void validate(Class<?> aspectClass) throws AopConfigException;
List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory);
@Nullable
Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrder, String aspectName);
@Nullable
Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName);
}
DefaultAdvisorAutoProxyCreator
擴充isEligibleAdvisorBean,通過配置的prefix來過濾adivisor bean。
@Override
protected boolean isEligibleAdvisorBean(String beanName) {
if (!isUsePrefix()) {
return true;
}
String prefix = getAdvisorBeanNamePrefix();
return (prefix != null && beanName.startsWith(prefix));
}
InfrastructureAdvisorAutoProxyCreator
擴充isEligibleAdvisorBean,這個過濾條件是,隻選擇架構級别(beanDefinition的role為ROLE_INFRASTRUCTURE)的Adivisor來進行對符合條件的對象進行織入,生成代理。
@Override
protected boolean isEligibleAdvisorBean(String beanName) {
return (this.beanFactory != null && this.beanFactory.containsBeanDefinition(beanName) &&
this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);
}