文章目录
- AOP系列文章链接地址
- 前言
- 代码块一:postProcessAfterInitialization
- 代码块二:wrapIfNecessary
- 代码块三:getAdvicesAndAdvisorsForBean
- 代码块四:findEligibleAdvisors
- 代码块五:findCandidateAdvisors
- 代码块六:findCandidateAdvisors
- 代码块七:buildAspectJAdvisors
- 代码块八:getAdvisors
- 代码块九:getAdvisor
- 代码块十:getPointcut
- 代码块十一:findAspectJAnnotationOnMethod
- 代码块十二:new InstantiationModelAwarePointcutAdvisorImpl
- 代码块十三:instantiateAdvice
- 代码块十四:findAdvisorsThatCanApply
- 代码块十五:canApply
- 代码块十六:createProxy
- 代码块十七:getProxy
- new JdkDynamicAopProxy和new CglibAopProxy
- JdkDynamicAopProxy&getProxy
- CglibAopProxy& getProxy
- 代码块十八 getCallbacks
- 代码块十九:ProxyCallbackFilter accept()
AOP系列文章链接地址
Spring AOP系列学习笔记一:AOP简介
Spring AOP系列学习笔记二:AOP入口分析
Spring AOP系列学习笔记三:AOP注解原理分析
Spring AOP系列学习笔记四:AOP具体调用流程分析
前言
前面我们介绍了aop基于xml和注解的入口,下面我们正式进入解析的过程。在解析BeanPostProcessor 接口的时候已经介绍过了,在bean初始化的前后会分别调用postProcessBeforeInitialization和postProcessAfterInitialization,AnnotationAwareAspectJAutoProxyCreator或者其父类实现了BeanPostProcessor接口,下面进入该方法。
代码块一:postProcessAfterInitialization
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
1、从缓存中获取
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
2、对bean进行封装
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
2、对bean进行分装见代码块二
代码块二:wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
1、判断targetSourcedBeans有无缓存
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
2、判断advisedBeans是否有缓存
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
3、当前bean是Aop的基础类,或者应该跳过创建代理
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
4、获取当前bean的增强器,也可以理解为切面(自己的理解)
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
4.1、创建代理,这儿SingletonTargetSource存放的是被代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
4.2、存放到缓存中
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
5、走到这儿,说明要代理的bean已经生成代理或者没有代理,标记为无需处理。
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
4、获取当前bean的增强器,也可以理解为切面(自己的理解)见代码块三
4.1、创建代理 见代码块十六
代码块三:getAdvicesAndAdvisorsForBean
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
1、查找符合条件的代理类
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
1、查找符合条件的代理类见代码块四
代码块四:findEligibleAdvisors
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
1、查找所有的所有代理类(Advisor)
List<Advisor> candidateAdvisors = findCandidateAdvisors();
2、筛选出符合当前bean的代理类
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
3、扩展方法
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
4、进行排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
1、查找所有的所有代理类(Advisor)见代码块五
2、筛选出符合当前bean的代理类见代码块十四
代码块五:findCandidateAdvisors
@Override
protected List<Advisor> findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
1、找到所有的Spring顾问
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
2、为bean工厂所有的AspectJ方面构建advisor
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
1、找到所有的Advisor 见代码块六
2、为bean工厂所有的AspectJ方面构建advisor见代码块七
代码块六:findCandidateAdvisors
protected List<Advisor> findCandidateAdvisors() {
return this.advisorRetrievalHelper.findAdvisorBeans();
}
public List<Advisor> findAdvisorBeans() {
// 1.确认advisor的beanName列表,优先从缓存中拿
String[] advisorNames = null;
synchronized (this) {
advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// 1.1 如果缓存为空,则获取class类型为Advisor的所有bean名称
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
}
if (advisorNames.length == 0) {
return new LinkedList<Advisor>();
}
// 2.遍历处理advisorNames
List<Advisor> advisors = new LinkedList<Advisor>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
// 2.1 跳过当前正在创建的advisor
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping currently created advisor '" + name + "'");
}
} else {
try {
// 2.2 通过beanName获取对应的bean对象,并添加到advisors
advisors.add(this.beanFactory.getBean(name, Advisor.class));
} catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
if (this.beanFactory.isCurrentlyInCreation(bce.getBeanName())) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping advisor '" + name +
"' with dependency on currently created bean: " + ex.getMessage());
}
// Ignore: indicates a reference back to the bean we're trying to advise.
// We want to find advisors other than the currently created bean itself.
continue;
}
}
throw ex;
}
}
}
}
// 3.返回符合条件的advisor列表
return advisors;
}
代码块七:buildAspectJAdvisors
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
1、先验证缓存中是否已经存在
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new LinkedList<>();
aspectNames = new LinkedList<>();
2、获取所有的beanName
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
3.1、不合法的beanName则跳过,默认返回true
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.
3.2、获取beanName对应的类型
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
3.3、该类是否存在@Aspect注解
if (this.advisorFactory.isAspect(beanType)) {
4、使用了注解,添加到缓存中
aspectNames.add(beanName);
4.1、构建一个切面的元数据
AspectMetadata amd = new AspectMetadata(beanType, beanName);
4.2、判断切面per-clause是否是单例的
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
4.3、使用BeanFactory和beanName创建一个BeanFactoryAspectInstanceFactory,主要用来创建切面对象实例
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
4.4、解析切面的增强方法
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
4.5、如果切面是单例的,则直接放到缓存中
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
4.6、如果切面是多例的则,先放入到factory缓存,每次获取的时候用factory去解析
this.aspectFactoryCache.put(beanName, factory);
}
4.7、将解析的增强器添加到advisors,后面作为方法的返回值
advisors.addAll(classAdvisors);
}
else {
// Per target or per this.
4.8、如果per-clause是多例的,但是切面beanName是单例的,直接抛出异常
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);
4.9、都是多例,则先放入到factory缓存中,以后从factory解析使用
this.aspectFactoryCache.put(beanName, factory);
4.10、解析标记AspectJ注解中的增强方法,并添加到advisors中
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
5、走到这儿,说明aspectNames不是null,已经解析过了
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
List<Advisor> advisors = new LinkedList<>();
for (String aspectName : aspectNames) {
5.1、从上面放入的缓存中获取,在这个缓存中说明都已经解析过了,直接放入到advisors
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
else {
5.2、从aspectFactoryCache中拿到缓存的factory,然后解析出增强器,添加到结果中
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
4.4、解析切面的增强方法见代码块八
代码块八:getAdvisors
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
1、获取当前的切面类
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
2、获取切面类名字
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
3、校验切面类
validate(aspectClass);
// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
// so that it will only instantiate once.
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new LinkedList<>();
4、获取切面类中的方法(也就是我们用来进行逻辑增强的方法,被@Around、@After等注解修饰的方法,使用@Pointcut的方法不处理)
for (Method method : getAdvisorMethods(aspectClass)) {
4.1、处理method
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()) {
5、如果寻找的增强器不为空而且又配置了增强延迟初始化,那么需要在首位加入同步实例化增强器(用以保证增强使用之前的实例化)
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
// Find introduction fields.
6、获取DeclareParents注解
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
4.1、处理method 见代码块九
代码块九:getAdvisor
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
1、校验切面类
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
2、获取切点表达式,如:@Around("execution(* com.joonwhee.open.aop.*.*(..))")
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
3、如果expressionPointcut为null,则直接返回null
if (expressionPointcut == null) {
return null;
}
4、进行包装,返回增强器
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
2、获取切点表达式 见代码块十
4、进行包装,返回增强器见代码块十二
代码块十:getPointcut
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
1.查找并返回给定方法的第一个AspectJ注解(@Before, @Around, @After, @AfterReturning, @AfterThrowing, @Pointcut)
因为我们之前把@Pointcut注解的方法跳过了,所以这边必然不会获取到@Pointcut注解
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
2.如果方法没有使用AspectJ的注解,则返回null
if (aspectJAnnotation == null) {
return null;
}
3.使用AspectJExpressionPointcut实例封装获取的信息
AspectJExpressionPointcut ajexp =
new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
提取得到的注解中的表达式,
例如:@Around("execution(* com.joonwhee.open.aop.*.*(..))"),得到:execution(* com.joonwhee.open.aop.*.*(..))
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
ajexp.setBeanFactory(this.beanFactory);
return ajexp;
}
1.查找并返回给定方法的AspectJ注解见代码块十一
代码块十一:findAspectJAnnotationOnMethod
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
1、设置要查找的注解类
Class<?>[] classesToLookFor = new Class<?>[] {
Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
2、查找方法上是否存在当前遍历的注解,如果有则返回
for (Class<?> c : classesToLookFor) {
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) c);
if (foundAnnotation != null) {
return foundAnnotation;
}
}
return null;
}
代码块十二:new InstantiationModelAwarePointcutAdvisorImpl
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
1.简单的将信息封装在类的实例中
this.declaredPointcut = declaredPointcut;
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
this.methodName = aspectJAdviceMethod.getName();
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
aspectJAdviceMethod保存的是我们用来进行逻辑增强的方法(@Around、@After等修饰的方法)
this.aspectJAdviceMethod = aspectJAdviceMethod;
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
this.aspectInstanceFactory = aspectInstanceFactory;
this.declarationOrder = declarationOrder;
this.aspectName = aspectName;
2.是否需要延迟实例化
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;
3.实例化增强器:根据注解中的信息初始化对应的增强器
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
}
3.实例化增强器:根据注解中的信息初始化对应的增强器见代码块十三
代码块十三:instantiateAdvice
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
1、获取切面的增强方法
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
return (advice != null ? advice : EMPTY_ADVICE);
}
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
1、获取切面类
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
2、校验切面类
validate(candidateAspectClass);
3、返回起一个AspectJ注解如:Before, Around, After, AfterReturning, AfterThrowing, 在这儿获取不到point
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
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;
4、判断使用的注解,生成对应的增强包装类
switch (aspectJAnnotation.getAnnotationType()) {
case AtBefore:
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;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
// Now to configure the advice...
5、配置增强器
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
}
代码块十四:findAdvisorsThatCanApply
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
1、进行筛选,获取符合条件的切面
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new LinkedList<>();
for (Advisor candidate : candidateAdvisors) {
1、首先处理引介增强(@DeclareParents)用的比较少可以忽略
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
2、遍历所有的切面
for (Advisor candidate : candidateAdvisors) {
2.1、引介增强已经处理,直接跳过
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
2.2、正常增强处理,判断当前bean是否可以应用于当前遍历的增强器
(bean是否包含在增强器的execution指定的表达式中)
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
2.2、正常增强处理,判断当前bean是否可以应用于当前遍历的增强器见代码块十五
代码块十五:canApply
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
1、确定切入点是否适合当前类
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
1、判断当前类是否匹配表达式
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
2、如果增强方法匹配所有方法,则直接返回true
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
Set<Class<?>> classes = new LinkedHashSet<>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
classes.add(targetClass);
for (Class<?> clazz : classes) {
3、获取被代理类的所有方法
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
3.1、增强方法匹配不为空&&该方法符合表达式||符合方法表达式(自己没懂)
if ((introductionAwareMethodMatcher != null &&
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
代码块十六:createProxy
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);
1、判断被代理类是基于接口代理还是类代理
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
1.1、若基于类代理,则proxyTargetClass属性设置为true
proxyFactory.setProxyTargetClass(true);
}
else {
1.2、评估bean的代理接口
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
2、构建增强器
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
3、设置被代理的类
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
4、用来控制proxyFactory被配置之后,是否还允许修改通知。默认值为false(即在代理被配置之后,不允许修改代理类的配置)
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
5、获取代理
return proxyFactory.getProxy(getProxyClassLoader());
}
5、获取代理见代码块十七
代码块十七:getProxy
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
// 1.激活此代理配置
activate();
}
// 2.创建AopProxy
return getAopProxyFactory().createAopProxy(this);
}
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 1.判断使用JDK动态代理还是Cglib代理
// optimize:用于控制通过cglib创建的代理是否使用激进的优化策略。除非完全了解AOP如何处理代理优化,
// 否则不推荐使用这个配置,目前这个属性仅用于cglib代理,对jdk动态代理无效
// proxyTargetClass:默认为false,设置为true时,强制使用cglib代理,设置方式:<aop:aspectj-autoproxy proxy-target-class="true" />
// hasNoUserSuppliedProxyInterfaces:config是否存在代理接口或者只有SpringProxy一个接口
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
// 拿到要被代理的对象的类型
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
// TargetSource无法确定目标类:代理创建需要接口或目标。
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
// 要被代理的对象是接口 || targetClass是Proxy class
// 当且仅当使用getProxyClass方法或newProxyInstance方法动态生成指定的类作为代理类时,才返回true。
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
// JDK动态代理,这边的入参config(AdvisedSupport)实际上是ProxyFactory对象
// 具体为:AbstractAutoProxyCreator中的proxyFactory.getProxy发起的调用,在ProxyCreatorSupport使用了this作为参数,
// 调用了的本方法,这边的this就是发起调用的proxyFactory对象,而proxyFactory对象中包含了要执行的的拦截器
return new JdkDynamicAopProxy(config);
}
// Cglib代理
return new ObjenesisCglibAopProxy(config);
} else {
// JDK动态代理
return new JdkDynamicAopProxy(config);
}
}
new JdkDynamicAopProxy和new CglibAopProxy
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
}
public CglibAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
this.advisedDispatcher = new AdvisedDispatcher(this.advised);
}
这儿把config都设置到了对应的代理类中。
getProxy()方法也会走对应的代理类中的方法。
JdkDynamicAopProxy&getProxy
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
1、获取被代理的所有的接口
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
2、.通过classLoader、接口、InvocationHandler实现类,来获取到代理对象
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
在CglibAopProxy的getProxy()方法简单介绍一下,代码主要关注一下getCallbacks()这个方法。
CglibAopProxy& getProxy
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
1、获取被代理的原始类
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
2、CGLIB_CLASS_SEPARATOR 是字符串 $$
说明当前类已经是cglib代理类了
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
3、携带所有cglib所需的配置信息,后续用于反射创建代理对象
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
4、配置代理类需要实现的接口,一般是SpringProxy和Advised
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
5、获取代理所需的所有拦截器,后续通过ProxyCallbackFilter内部类进行确定使用的具体拦截器
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);
}
}
5、获取代理所需的所有拦截器,后续通过ProxyCallbackFilter内部类进行确定使用的具体拦截器 见代码块十六 和代码块十七
代码块十八 getCallbacks
获取该方法的所有拦截器
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// Parameters used for optimization choices...
1、是否需要对外暴露
boolean exposeProxy = this.advised.isExposeProxy();
2、是否冻结
boolean isFrozen = this.advised.isFrozen();
3、是否是单例的
boolean isStatic = this.advised.getTargetSource().isStatic();
// Choose an "aop" interceptor (used for AOP calls).
4、AOP默认的拦截器,我们自己写的大部分场景用的也都是这个拦截器
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;
5、是否对外暴露
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).
6、直接调用目标方法
Callback targetDispatcher = (isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());
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.
7、是单例的并且被冻结
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = CollectionUtils.newHashMap(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];
7.1、获取符合被代理方法的所有增强,这儿提前获取并封装到拦截器中了,正常是在拦截器的
intercept()方法内获取到调用链,就是代理生成之后无法再修改
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(method, 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;
}
代码块十九:ProxyCallbackFilter accept()
确定具体使用哪个拦截器
@Override
public int accept(Method method) {
1、是否被final修饰,则不代理
if (AopUtils.isFinalizeMethod(method)) {
logger.trace("Found finalize() method - using NO_OVERRIDE");
return NO_OVERRIDE;
}
2、不透明&&方法所在类是接口&&实现了Advised
if (!this.advised.isOpaque() && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
if (logger.isTraceEnabled()) {
logger.trace("Method is declared on Advised interface: " + method);
}
return DISPATCH_ADVISED;
}
// We must always proxy equals, to direct calls to this.
3、equal方法
if (AopUtils.isEqualsMethod(method)) {
if (logger.isTraceEnabled()) {
logger.trace("Found 'equals' method: " + method);
}
return INVOKE_EQUALS;
}
// We must always calculate hashCode based on the proxy.
4、HashCode方法
if (AopUtils.isHashCodeMethod(method)) {
if (logger.isTraceEnabled()) {
logger.trace("Found 'hashCode' method: " + method);
}
return INVOKE_HASHCODE;
}
Class<?> targetClass = this.advised.getTargetClass();
// Proxy is not yet available, but that shouldn't matter.
5、获取符合该方法的增强
List<?> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
boolean haveAdvice = !chain.isEmpty();
boolean exposeProxy = this.advised.isExposeProxy();
boolean isStatic = this.advised.getTargetSource().isStatic();
boolean isFrozen = this.advised.isFrozen();
6、有无增强
if (haveAdvice || !isFrozen) {
// If exposing the proxy, then AOP_PROXY must be used.
6.1、是否对外暴露
通过AopContext.setCurrentProxy()获取对外暴露的代理对象;
if (exposeProxy) {
if (logger.isTraceEnabled()) {
logger.trace("Must expose proxy on advised method: " + method);
}
return AOP_PROXY;
}
// Check to see if we have fixed interceptor to serve this method.
// Else use the AOP_PROXY.
6.2、单例&&冻结&& 在getCallbacks方法中是否添加到了fixedInterceptorMap
if (isStatic && isFrozen && this.fixedInterceptorMap.containsKey(method)) {
if (logger.isTraceEnabled()) {
logger.trace("Method has advice and optimizations are enabled: " + method);
}
// We know that we are optimizing so we can use the FixedStaticChainInterceptors.
int index = this.fixedInterceptorMap.get(method);
return (index + this.fixedInterceptorOffset);
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Unable to apply any optimizations to advised method: " + method);
}
6.3、使用AOP
return AOP_PROXY;
}
}
else {
7、没有增强
// See if the return type of the method is outside the class hierarchy of the target type.
// If so we know it never needs to have return type massage and can use a dispatcher.
// If the proxy is being exposed, then must use the interceptor the correct one is already
// configured. If the target is not static, then we cannot use a dispatcher because the
// target needs to be explicitly released after the invocation.
7.1、暴露当前代理类 && 代理类不是单例
if (exposeProxy || !isStatic) {
return INVOKE_TARGET;
}
Class<?> returnType = method.getReturnType();
7.2、方法的返回值还是本身
if (targetClass != null && returnType.isAssignableFrom(targetClass)) {
if (logger.isTraceEnabled()) {
logger.trace("Method return type is assignable from target type and " +
"may therefore return 'this' - using INVOKE_TARGET: " + method);
}
return INVOKE_TARGET;
}
else {
7.3、直接执行目标方法
if (logger.isTraceEnabled()) {
logger.trace("Method return type ensures 'this' cannot be returned - " +
"using DISPATCH_TARGET: " + method);
}
return DISPATCH_TARGET;
}
}
}
最终,通过 CGLIB 代理的类被调用时,会走到对应拦截器,如常用的DynamicAdvisedInterceptor#intercept 方法。