文章目錄
編寫bean
@AllArgsConstructor
@Data
@NoArgsConstructor
public class MyBeanTest implements InitializingBean, DisposableBean {
private String testStr = "testStr";
public void test() {
System.out.println(testStr);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean");
}
@Override
public void destroy() throws Exception {
System.out.println("死了");
}
}
編寫需要Advisor
// 指定當前類爲切面類
@Aspect
public class AopTest {
/**
* 指定切入點表達式,攔截那些方法,那些方法就生成代理對象。
*/
@Pointcut("execution (* *.test(..))")
public void test() {
}
//前置通知:執行目標方法之前執行
@Before("test()")
public void begin() {
System.out.println("開啓事務");
}
//後置通知:執行目標方法之後執行,是否出現異常都會執行。
@After("test()")
public void commit() {
System.out.println("提交事務");
}
// 異常通知:目標方法執行出現異常,執行此關注代碼
@AfterThrowing("test()")
public void afterThrowing() {
System.out.println("afterThrowing");
}
//返回後通知:在調用目標方法結束後執行,出現異常不執行。
@AfterReturning("test()")
public void afterReturning() {
System.out.println("AfterReturning");
}
//環繞通知:環繞目標方法執行
@Around("test()")
public void around(ProceedingJoinPoint pj) throws Throwable {
System.out.println("環繞前");
pj.proceed();//執行目標方法
System.out.println("環繞後");
}
}
配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--開啓aop-->
<aop:aspectj-autoproxy/>
<bean id="myTestBean" class="org.example.MyBeanTest"></bean>
<!--測試aop,需要導入名稱空間 -->
<bean class="org.example.aop.AopTest"/>
<!--加載時織入,LTW 靜態AOP示例,需要配置aop.xml
啓動時候需要加入:"-javaagent:org.springframework.instrument.jar"}
虛擬機啓動時通過改變目標對象字節碼來完成對目標的增強,比動態代理更有效率
底層依賴instrument類庫
org.springframework.context.config.LoadTimeWeaverBeanDefinitionParser.doParse
-->
<!-- <context:load-time-weaver />-->
</beans>
執行流程,主要是根據spring-aop/src/main/resources/META-INF/spring.handlers注入的配置命名空間處理器
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
可以看到aspectj-autoproxy這個屬性,正是配置文件聲明AOP的命名空間.
public class AopNamespaceHandler extends NamespaceHandlerSupport {
/**
* Register the {@link BeanDefinitionParser BeanDefinitionParsers} for the
* '{@code config}', '{@code spring-configured}', '{@code aspectj-autoproxy}'
* and '{@code scoped-proxy}' tags.
*/
@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());
}
}
查看他的接口,發現只有這一個方法,說明就是根據這個執行的解析命名空間
public interface BeanDefinitionParser {
@Nullable
BeanDefinition parse(Element element, ParserContext parserContext);
}
現在進入AspectJAutoProxyBeanDefinitionParser類解析parse
/*
註冊AnnotationAwareAspectJAutoProxyCreator
對於註解中子類的處理
*/
public BeanDefinition parse(Element element, ParserContext parserContext) {
//註冊AnnotationAwareAspectJAutoProxyCreator
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
//對於註解中子類的處理
extendBeanDefinition(element, parserContext);
return null;
}
/*
註冊或升級AutoProxyCreator定義beanName爲internalAutoProxyCreator的BeanDefinition
對於proxy-target-class以及expose-proxy屬性的處理
註冊組件並通知,便於監聽器做進一步處理
*/
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
//註冊或升級AutoProxyCreator定義beanName爲internalAutoProxyCreator的BeanDefinition
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
//對於proxy-target-class以及expose-proxy屬性的處理
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
//註冊組件並通知,便於監聽器做進一步處理
registerComponentIfNecessary(beanDefinition, parserContext);
}
/*
設置默認org.springframework.aop.config.AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME
*/
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
//aop的實現基本都是AnnotationAwareAspectJAutoProxyCreator完成的,他可以根據@Point定義的切點自動代理相匹配的bean
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
/*
創建AUTO_PROXY_CREATOR_BEAN_NAME
*/
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//如果已經存在了自動代理創建器且存在的創建器與現在的不一致那麼需要根據優先級判斷到底使用哪個
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
//根據優先級判斷使用哪個
if (currentPriority < requiredPriority) {
//改變bean所對應的className屬性
apcDefinition.setBeanClassName(cls.getName());
}
}
//如果已經存在自動代理創建器並且與將要創建的一致,那麼無需創建
return null;
}
//聲明AnnotationAwareAspectJAutoProxyCreator註冊爲新的RootBeanDefinition
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;
}
/*
對XML元素proxy-target-class和expose-proxy的處理
*/
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, @Nullable Element sourceElement) {
if (sourceElement != null) {
/*
使用jdk代理和cglib,
使用cglib需要注意
無法通知(advise)Final方法,因爲不能被重寫
需要將cglib二進制發行包放在classpath下面
強制使用cglib,需要設置true
<aop:aspectj-autoproxy proxy-target-class="true"/>
*/
//配置是否有proxy-target-class屬性
boolean proxyTargetClass = Boolean.parseBoolean(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
if (proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
//有時候目標對象內部的自我調用無法實現切面中的增強
//當嵌套事務的時候,內部事務不會代理,如果想要子事務代理,則需要設置expose-proxy=true,同時在父事務使用AopContext.currentProxy()執行子事務
boolean exposeProxy = Boolean.parseBoolean(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
if (exposeProxy) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
// proxyTargetClass屬性設置
public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
}
}
// exposeProxy屬性設置
public static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
}
}
至止加載命名空間解析器完成.
接下來來看看他的切點到底是什麼時候執行的.首先看註冊的默認AnnotationAwareAspectJAutoProxyCreator接口層次
可以發現主要實現了Aware和BeanPostProcessor,Aware主要是資源的獲取跟我們想要的無關.BeanPostProcessor在每次bean初始化的時候執行,我們看實現的方法
/*
構建key
封裝對象
*/
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
//構建key,工廠bean格式&beanName
Object cacheKey = getCacheKey(bean.getClass(), beanName);
//創建對象完成後賦值之前,利用工廠創建了bean,同時添加到了earlyProxyReferences進行代理,主要避免循環依賴
//主要看org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean
//但該對象創建完成後,表明不在需要利用工廠創建對象,從而避免循環依賴的問題,於是該對象可以刪除
//如果刪除對象和bean一致,說明對象一樣,不需要進行代理
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
//封裝指定bean
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
/*
獲取緩存bean
判斷是否增強
判斷是否基礎設施類
獲取增強方法並進行代理
加入緩存
*/
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//如果已經處理過
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//無需增強
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
//給定的bean類是否代表一個基礎設施類,基礎設施類不應代理,或者配置了指定的bean不需要代理
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
//如果存在增強方法則創建代理
// Create proxy if we have 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;
}
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) {
//獲取所有增強器
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//尋找匹配增強器
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
//執行擴展,子類可覆蓋
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
//排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
獲取所有增強器
/*
獲取所有aop聲明
*/
protected List<Advisor> findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
//調用父類加載配置文件aop聲明
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
//獲取容器所有切面aop聲明
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
/*
獲取所有的beanName並遍歷
找出beanName對應的calss是否存在Aspect註解
解析註解標記的增強方法
記錄緩存並返回
*/
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
//獲取所有beanName
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
//循環找出所有beanName對應的增強方法
for (String beanName : beanNames) {
//不合法beanName跳過
if (!isEligibleBean(beanName)) {
continue;
}
// We must be careful not to instantiate beans eagerly as in this case they
// would be cached by the Spring container but would not have been weaved.
//獲取對應beanName的class類型
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
//如果存在Aspect註解,同時沒有ajc$字段
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
//分別封裝bean的name和class
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
//解析註解標記的增強方法
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
// Per target or per this.
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;
}
/*
驗證
獲取本類包括父類接口非PointCut註解所有公有方法
獲取方法上註解符合預定於註解的增強器
同步實例化增強器
獲取DeclareParents註解的方法增強器
*/
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
//獲取標記爲AspectJ的類
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
//獲取標記爲AspectJ的name
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
//驗證
validate(aspectClass);
// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
// so that it will only instantiate once.
//裝飾延遲初始化的AspectInstanceFactory
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList<>();
//獲取本類包括父類接口非PointCut註解所有公有方法
for (Method method : getAdvisorMethods(aspectClass)) {
//獲取方法上註解符合預定於註解的增強器
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
// If it's a per target aspect, emit the dummy instantiating aspect.
//同步實例化增強器
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
//如果尋找的增強器不爲空,且有配置了增強延遲初始化那麼需要在首位加入同步實例化增強器,保證增強之前對bean的實例化
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
// Find introduction fields.
//獲取DeclareParents註解
//獲取引介增強的註解形式實現
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
/*
校驗
切點信息獲取
根據切點信息生成增強器
*/
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
//校驗
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
//切點信息獲取,主要封裝了表達式和class,name
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
//根據切點信息生成增強器
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
/*
獲取匹配預定義註解對應方法上的註解
封裝獲取信息
封裝提取得到的表達式以及工廠
*/
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
//獲取匹配預定義註解對應方法上的註解
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
//封裝獲取信息
AspectJExpressionPointcut ajexp =
new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
//提取得到的表達式,如:@around(“test()”)的test()
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
if (this.beanFactory != null) {
ajexp.setBeanFactory(this.beanFactory);
}
return ajexp;
}
/*
匹配預定義的方法註解
*/
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
//ASPECTJ_ANNOTATION_CLASSES:需要匹配註解的類提前類靜態加載了
for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
//獲取指定方法上的註解
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
if (foundAnnotation != null) {
return foundAnnotation;
}
}
return null;
}
/*
這裏主要封裝一些信息
以及針對不同註解生成不同註解器解析
*/
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
this.declaredPointcut = declaredPointcut;
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
this.methodName = aspectJAdviceMethod.getName();
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
this.aspectJAdviceMethod = aspectJAdviceMethod;
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
this.aspectInstanceFactory = aspectInstanceFactory;
this.declarationOrder = declarationOrder;
this.aspectName = aspectName;
if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
// Static part of the pointcut is a lazy type.
Pointcut preInstantiationPointcut = Pointcuts.union(
aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
// Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
// If it's not a dynamic pointcut, it may be optimized out
// by the Spring AOP infrastructure after the first evaluation.
this.pointcut = new PerTargetInstantiationModelPointcut(
this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
this.lazy = true;
}
else {
// A singleton aspect.
this.pointcut = this.declaredPointcut;
this.lazy = false;
//根據註解中的信息初始化對應的增強器,如@Before和@After分別初始化不同增強器
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
}
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
// 根據註解不同獲取不同增強器
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
return (advice != null ? advice : EMPTY_ADVICE);
}
/*
驗證
封裝註解類型以及切點表達式
判斷是否類上有Aspect註解
根據註解不同封裝不同增強器
配置Advice
*/
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
//校驗
validate(candidateAspectClass);
//封裝註解類型以及切點表達式
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
// If we get here, we know we have an AspectJ method.
// Check that it's an AspectJ-annotated class
//判斷是否類上有Aspect註解
if (!isAspect(candidateAspectClass)) {
throw new AopConfigException("Advice must be declared inside an aspect type: " +
"Offending method '" + candidateAdviceMethod + "' in class [" +
candidateAspectClass.getName() + "]");
}
if (logger.isDebugEnabled()) {
logger.debug("Found AspectJ method: " + candidateAdviceMethod);
}
AbstractAspectJAdvice springAdvice;
//根據註解不同封裝不同增強器
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore:
//MethodBeforeAdviceInterceptor
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
// Now to configure the advice...
springAdvice.setAspectName(aspectName);
//添加到Advice集合的索引
springAdvice.setDeclarationOrder(declarationOrder);
//獲取方法註解配置的argNames
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
}
protected static class SyntheticInstantiationAdvisor extends DefaultPointcutAdvisor {
/*
同步實例化增強器初始化
*/
public SyntheticInstantiationAdvisor(final MetadataAwareAspectInstanceFactory aif) {
super(aif.getAspectMetadata().getPerClausePointcut(),
//目標方法前調用,類似@Before
(MethodBeforeAdvice)(method, args, target) ->
//簡單初始化aspect
aif.getAspectInstance());
}
}
尋找匹配增強器
/*
過濾已經得到的advisors
*/
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);//設置當前代理的名稱
try {
//過濾已經得到的advisors
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);//clear代理的名稱
}
}
/*
空判斷
處理引介增強和普通增強器
*/
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
//空判斷
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new ArrayList<>();
//首先處理引介增強,引介增強與其他普通增強處理不一樣,所以單獨處理
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
//引介增強已經處理
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
//對於普通bean的處理,canApply主要做匹配
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
獲取Advisor
/*
暴露目標類
設置代理接口
封裝所有的攔截器增強器加入proxyFactory
子類擴展
獲取代理對象
*/
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);
//不直接代理目標類以及任何接口。
if (!proxyFactory.isProxyTargetClass()) {
//確定對於給定的bean是否應該使用TargetClass而不是他的接口代理
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);
//用來控制代理工廠被配置之後,是否還允許修改通知
//默認false,在代理配置之後不允許修改代理的配置
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//獲取代理對象
return proxyFactory.getProxy(getProxyClassLoader());
}
/*
注入攔截器,包括提前設置的interceptorNames
轉換成Advisor
*/
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
// Handle prototypes correctly...
//註冊所有的InterceptorName
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[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
//攔截器轉換成Advisor
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}
/*
解析InterceptorNames並封裝成Advisor
*/
private Advisor[] resolveInterceptorNames() {
BeanFactory bf = this.beanFactory;
ConfigurableBeanFactory cbf = (bf instanceof ConfigurableBeanFactory ? (ConfigurableBeanFactory) bf : null);
List<Advisor> advisors = new ArrayList<>();
for (String beanName : this.interceptorNames) {
if (cbf == null || !cbf.isCurrentlyInCreation(beanName)) {
Assert.state(bf != null, "BeanFactory required for resolving interceptor names");
Object next = bf.getBean(beanName);
//封裝成Advisor
advisors.add(this.advisorAdapterRegistry.wrap(next));
}
}
return advisors.toArray(new Advisor[0]);
}
/*
將AdvisorAdapter以及MethodInterceptor轉換以及封裝成Advisor
*/
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
//如果封裝對象是Advisor,無需處理
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
//非Advisor和Advice無法封裝
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
//使用DefaultPointcutAdvisor封裝
return new DefaultPointcutAdvisor(advice);
}
//如果存在Advisor的適配器也需要封裝
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
加載代理
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
protected final synchronized AopProxy createAopProxy() {
//是否激活狀態
if (!this.active) {
//激活代理配置
activate();
}
//創建代理
return getAopProxyFactory().createAopProxy(this);
}
/*
創建CGLIB或者JDK動態代理
*/
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
/*
optimize:只對cglib有效,控制cglib是否採用激進的優化策略
proxyTargetClass:true則表示cglib代理,而且表示目標類本身被代理而不是目標類的接口
hasNoUserSuppliedProxyInterfaces:是否存在代理接口
*/
//如果開啓cglib激進策略,proxy-target-class=true(表示目標類本身被代理,採用cglib),存在代理接口
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
//如果代理類是接口,targetClass是代理類
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
CGLIB代理
/*
設置CGLIB屬性
獲取攔截器鏈
設置攔截器鏈創建代理
*/
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
//獲取目標類
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
//是否cglig代理類
if (ClassUtils.isCglibProxyClass(rootClass)) {
//獲取父類
proxySuperClass = rootClass.getSuperclass();
//獲取接口
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
//添加接口到Advised
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
//驗證class
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
//創建以及配置Enhancer
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
//獲取攔截器鏈
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
//設置調用過濾器
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
//設置攔截器鏈,生成代理類,以及創建代理
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
/*
主要添加7個攔截器鏈
*/
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// Parameters used for optimization choices...
//對於exposeProxy的處理
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
// Choose an "aop" interceptor (used for AOP calls).
//將攔截器封裝到DynamicAdvisedInterceptor中
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
// Choose a "straight to target" interceptor. (used for calls that are
// unadvised but can return this). May be required to expose the proxy.
Callback targetInterceptor;
if (exposeProxy) {
targetInterceptor = (isStatic ?
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
}
else {
targetInterceptor = (isStatic ?
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
}
// Choose a "direct to target" dispatcher (used for
// unadvised calls to static targets that cannot return this).
Callback targetDispatcher = (isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());
//加入攔截器到callbacks
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // for normal advice
targetInterceptor, // invoke target without considering advice, if optimized
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};
Callback[] callbacks;
// If the target is a static one and the advice chain is frozen,
// then we can make some optimizations by sending the AOP calls
// direct to the target using the fixed chain for that method.
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<>(methods.length);
// TODO: small memory optimization here (can skip creation for methods with no advice)
for (int x = 0; x < methods.length; x++) {
Method method = methods[x];
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(methods.toString(), x);
}
// Now copy both the callbacks from mainCallbacks
// and fixedCallbacks into the callbacks array.
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
this.fixedInterceptorOffset = mainCallbacks.length;
}
else {
callbacks = mainCallbacks;
}
return callbacks;
}
添加的攔截器
查看第一個執行攔截器鏈DynamicAdvisedInterceptor的intercept方法,其主要cglib調用增強
/*
串聯調用鏈
責任鏈模式
*/
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
//獲取攔截器鏈
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
//攔截器爲空直接激活原方法
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// We need to create a method invocation...
//進入鏈
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
@Override
@Nullable
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
//執行完所有增強後執行切點方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
//獲取下一個執行的攔截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
//動態匹配
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
//不匹配則不執行攔截器
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
//普通攔截器,直接調用,如:
//MethodBeforeAdviceInterceptor
//AspectJAroundAdvice
//AspectJAfterAdvice
//將this作爲參數傳遞,保證當前實例中調用鏈的執行
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
JDK代理
@Override
@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;
try {
//對equals處理
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
//對hashCode處理
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
//目標對象內部調用將無法使用切面,則需要暴露代理
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// Get the interception chain for this method.
//獲取當前方法的攔截器鏈
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
//如果沒有發現任何攔截器那麼直接調用切點方法
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// We need to create a method invocation...
//將攔截器封裝ReflectiveMethodInvocation
//便於使用其proceed進行鏈接表用攔截器
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
//執行攔截器鏈,這裏主要執行前置和後置等
retVal = invocation.proceed();
}
// Massage return value if necessary.
Class<?> returnType = method.getReturnType();
//返回結果
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}