mirror of
https://github.com/youthlql/JavaYouth.git
synced 2026-03-13 21:33:42 +08:00
1789 lines
70 KiB
Markdown
1789 lines
70 KiB
Markdown
---
|
||
title: Spring源码系列-第6章-AOP的后置处理器和代理对象的创建
|
||
tags:
|
||
- Spring源码
|
||
categories:
|
||
- Spring
|
||
- 源码V1
|
||
keywords: Spring,框架,spring源码
|
||
description: AOP源码
|
||
cover: 'https://npm.elemecdn.com/lql_static@latest/logo/spring.png'
|
||
abbrlink: 598f6b0d
|
||
date: 2022-03-19 12:01:02
|
||
---
|
||
|
||
|
||
|
||
# 第6章-AOP的后置处理器和代理对象的创建
|
||
|
||
## 测试类
|
||
|
||
### MainConfig
|
||
|
||
```java
|
||
@ComponentScan("cn.imlql.spring")
|
||
@Configuration
|
||
public class MainConfig {
|
||
|
||
public MainConfig(){
|
||
System.out.println("MainConfig...创建了....");
|
||
}
|
||
|
||
}
|
||
```
|
||
|
||
### AopOpenConfig
|
||
|
||
```java
|
||
@EnableAspectJAutoProxy //开启自动代理
|
||
@Configuration
|
||
public class AopOpenConfig {
|
||
|
||
|
||
}
|
||
```
|
||
|
||
### LogAspect
|
||
|
||
```java
|
||
/**
|
||
*
|
||
* 正常:前置通知===目标方法===返回通知===后置通知
|
||
* 异常: 前置通知===目标方法===异常通知===后置通知
|
||
* try{
|
||
* 前置通知
|
||
* 目标方法的执行
|
||
* 返回通知
|
||
* }catch(){
|
||
* 异常通知
|
||
* }finally{
|
||
* 后置通知
|
||
* }
|
||
*
|
||
*
|
||
*/
|
||
@Component //切面也是容器中的组件
|
||
@Aspect //说明这是切面
|
||
public class LogAspect {
|
||
|
||
public LogAspect(){
|
||
System.out.println("LogAspect...");
|
||
}
|
||
|
||
//前置通知 增强方法/增强器
|
||
@Before("execution(* cn.imlql.spring.aop.HelloService.sayHello(..))")
|
||
public void logStart(JoinPoint joinPoint){
|
||
String name = joinPoint.getSignature().getName();
|
||
System.out.println("logStart()==>"+name+"....【args: "+ Arrays.asList(joinPoint.getArgs()) +"】");
|
||
}
|
||
|
||
//返回通知
|
||
@AfterReturning(value = "execution(* cn.imlql.spring.aop.HelloService.sayHello(..))",returning = "result")
|
||
public void logReturn(JoinPoint joinPoint,Object result){
|
||
String name = joinPoint.getSignature().getName();
|
||
System.out.println("logReturn()==>"+name+"....【args: "+ Arrays.asList(joinPoint.getArgs()) +"】【result: "+result+"】");
|
||
}
|
||
|
||
|
||
//后置通知
|
||
@After("execution(* cn.imlql.spring.aop.HelloService.sayHello(..))")
|
||
public void logEnd(JoinPoint joinPoint){
|
||
String name = joinPoint.getSignature().getName();
|
||
System.out.println("logEnd()==>"+name+"....【args: "+ Arrays.asList(joinPoint.getArgs()) +"】");
|
||
}
|
||
|
||
|
||
//异常
|
||
@AfterThrowing(value = "execution(* cn.imlql.spring.aop.HelloService.sayHello(..))",throwing = "e")
|
||
public void logError(JoinPoint joinPoint,Exception e){
|
||
String name = joinPoint.getSignature().getName();
|
||
System.out.println("logError()==>"+name+"....【args: "+ Arrays.asList(joinPoint.getArgs()) +"】【exception: "+e+"】");
|
||
}
|
||
}
|
||
```
|
||
|
||
### HelloService
|
||
|
||
```java
|
||
@Component //切面存在的化就会返回代理对象
|
||
public class HelloService {
|
||
|
||
public HelloService(){
|
||
System.out.println("....");
|
||
}
|
||
|
||
public String sayHello(String name){
|
||
String result = "你好:"+name;
|
||
System.out.println(result);
|
||
int length = name.length();
|
||
return result + "---" + length;
|
||
}
|
||
}
|
||
```
|
||
|
||
### AnnotationMainTest
|
||
|
||
```java
|
||
package cn.imlql.spring;
|
||
|
||
|
||
import cn.imlql.spring.aop.HelloService;
|
||
import cn.imlql.spring.config.MainConfig;
|
||
import org.springframework.context.ApplicationContext;
|
||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||
|
||
/**
|
||
* 注解版Spring的用法
|
||
*/
|
||
public class AnnotationMainTest {
|
||
|
||
public static void main(String[] args) {
|
||
|
||
ApplicationContext applicationContext =
|
||
new AnnotationConfigApplicationContext(MainConfig.class);
|
||
|
||
//AOP,原理测试
|
||
HelloService helloService = applicationContext.getBean(HelloService.class);
|
||
helloService.sayHello("zhangsan");
|
||
}
|
||
}
|
||
```
|
||
|
||
## 如何分析Spring的一个新功能
|
||
|
||
对于一个Spring的新功能我们应该按照下面的思路分析:这个功能加入哪些组件?这些组件在生命周期期间做了什么?
|
||
|
||
1. 比如我们分析AOP
|
||
1. 分析AOP给容器添加了哪些组件,分析方法如下
|
||
1. **第一种方法:**之前讲过的给AbstractBeanDefinition三个构造器打断点,因为绝大多数组件都是要先经过Bean定义信息的。但也不排除Spring直接new组件注册进去,不经过AbstractBeanDefinition(很少很少)。所以此时再给容器刷新refresh()方法的最后一步finishRefresh()打个断点,看容器里此时有哪些组件即可。
|
||
2. **第二种方法**:Spring每开启一个功能,要么写配置要么写注解。Spring就要解析这些注解或者配置,Spring里面会有很多@EnableXXX这样的注解,顾名思义,就是开启什么什么功能。分析这种注解即可@EnableXXX,一般来说新功能大概率都是通过后置处理器做的,@EnableXXX肯定也是引入了新的后置处理器。
|
||
2. 这些组件在生命周期期间做了什么事。
|
||
|
||
## 分析@EnableXXX找到负责AOP功能的后置处理器
|
||
|
||
### @EnableAspectJAutoProxy
|
||
|
||
```java
|
||
@Target(ElementType.TYPE)
|
||
@Retention(RetentionPolicy.RUNTIME)
|
||
@Documented
|
||
@Import(AspectJAutoProxyRegistrar.class) //最核心的就是这个@Import了,导入了什么组件
|
||
public @interface EnableAspectJAutoProxy {
|
||
|
||
/**
|
||
* Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
|
||
* to standard Java interface-based proxies. The default is {@code false}.
|
||
*/
|
||
boolean proxyTargetClass() default false;
|
||
|
||
/**
|
||
* Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
|
||
* for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
|
||
* Off by default, i.e. no guarantees that {@code AopContext} access will work.
|
||
* @since 4.3.1
|
||
*/
|
||
boolean exposeProxy() default false;
|
||
|
||
}
|
||
```
|
||
|
||
#### AspectJAutoProxyRegistrar#registerBeanDefinitions()
|
||
|
||
```java
|
||
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
|
||
|
||
/**
|
||
* Register, escalate, and configure the AspectJ auto proxy creator based on the value
|
||
* of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
|
||
* {@code @Configuration} class.
|
||
*/
|
||
@Override
|
||
public void registerBeanDefinitions(
|
||
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
|
||
//注册切面的基于注解的自动代理创建器
|
||
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); //pos_1 在这里打个断点分析一下
|
||
|
||
AnnotationAttributes enableAspectJAutoProxy =
|
||
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
|
||
if (enableAspectJAutoProxy != null) {
|
||
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
|
||
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
|
||
}
|
||
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
|
||
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
```
|
||
|
||
|
||
|
||
### Debug调用栈
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211010202000109.png"/>
|
||
|
||
### ImportBeanDefinitionRegistrar
|
||
|
||
```java
|
||
default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,
|
||
BeanNameGenerator importBeanNameGenerator) {
|
||
|
||
registerBeanDefinitions(importingClassMetadata, registry);
|
||
}
|
||
```
|
||
|
||
最后就是这样的一个调用实现类
|
||
|
||
### AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary注册切面的基于注解的自动代理创建器
|
||
|
||
pos_1 Debug进去是下面的方法
|
||
|
||
```java
|
||
@Nullable
|
||
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
|
||
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
|
||
}
|
||
|
||
@Nullable
|
||
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
|
||
BeanDefinitionRegistry registry, @Nullable Object source) {
|
||
|
||
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
|
||
}
|
||
|
||
public static final String AUTO_PROXY_CREATOR_BEAN_NAME = "org.springframework.aop.config.internalAutoProxyCreator";
|
||
|
||
@Nullable
|
||
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) {
|
||
apcDefinition.setBeanClassName(cls.getName());
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
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后置处理器
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211010202725286.png"/>
|
||
|
||
我们发现这就是一个后置处理器,印证了我们之前说过的几乎所有功能增强或功能附加都是由后置处理器来完成
|
||
|
||
|
||
|
||
|
||
|
||
## AnnotationAwareAspectJAutoProxyCreator在生命周期期间做了什么事?
|
||
|
||
### 怎么分析?
|
||
|
||
1. 给getBean设置一个条件断点,条件就是BeanName==AnnotationAwareAspectJAutoProxyCreator的时候
|
||
2. 给AnnotationAwareAspectJAutoProxyCreator重写的父类的所有方法打上断点,因为它的最顶层接口是BeanPostProcessor 。最终肯定会一层一层往下调实现类实现的方法,大概率会调到AnnotationAwareAspectJAutoProxyCreator重写的方法。当然也不是绝对的,如果debug的时候发现没有停留,那就可以把所有方法都打上断点。或者你看方法名猜一下。
|
||
3. 我们这里是两个都做了
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
### 负责AOP功能的后置处理器第一次运行准备好数据
|
||
|
||
#### Debug调用栈-调用AnnotationAwareAspectJAutoProxyCreator的initBeanFactory()方法初始化AnnotationAwareAspectJAutoProxyCreator相关属性
|
||
|
||
##### 作用
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211011222513844.png"/>
|
||
|
||
1. 由于它是后置处理器所以肯定是在refresh方法里的registerBeanPostProcessors这一步开始干活的
|
||
2. 果然是从getBean调用到了我们的重写方法断点处,也就验证了我们上面说怎么分析。绿色包含的前面已经讲过,不再赘述。
|
||
3. 也确实是AnnotationAwareAspectJAutoProxyCreator,走到这里说明前面已经创建出了AnnotationAwareAspectJAutoProxyCreator对象(前面怎么创建的,getbean的流程之前已经讲的很清楚了),后面只是对AnnotationAwareAspectJAutoProxyCreator进行初始化
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211011225209123.png" />
|
||
|
||
##### AbstractAutowireCapableBeanFactory#initializeBean()进行初始化
|
||
|
||
注意此时这个参数bean就是AnnotationAwareAspectJAutoProxyCreator对象,往后走的过程中不要忘记
|
||
|
||
```java
|
||
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
|
||
if (System.getSecurityManager() != null) {
|
||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||
invokeAwareMethods(beanName, bean);
|
||
return null;
|
||
}, getAccessControlContext());
|
||
}
|
||
else {
|
||
invokeAwareMethods(beanName, bean); //组件有Aware接口,先Aware;BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
|
||
}
|
||
|
||
Object wrappedBean = bean;
|
||
if (mbd == null || !mbd.isSynthetic()) {//执行后置处理器的BeforeInitialization方法
|
||
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
|
||
}
|
||
|
||
try {
|
||
invokeInitMethods(beanName, wrappedBean, mbd);
|
||
}
|
||
catch (Throwable ex) {
|
||
throw new BeanCreationException(
|
||
(mbd != null ? mbd.getResourceDescription() : null),
|
||
beanName, "Invocation of init method failed", ex);
|
||
}
|
||
if (mbd == null || !mbd.isSynthetic()) { //
|
||
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
|
||
}
|
||
|
||
return wrappedBean;
|
||
}
|
||
|
||
|
||
private void invokeAwareMethods(String beanName, Object bean) {
|
||
if (bean instanceof Aware) {
|
||
if (bean instanceof BeanNameAware) {
|
||
((BeanNameAware) bean).setBeanName(beanName);
|
||
}
|
||
if (bean instanceof BeanClassLoaderAware) {
|
||
ClassLoader bcl = getBeanClassLoader();
|
||
if (bcl != null) {
|
||
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
|
||
}
|
||
}
|
||
if (bean instanceof BeanFactoryAware) {
|
||
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
##### AbstractAdvisorAutoProxyCreator#setBeanFactory()
|
||
|
||
```java
|
||
@Override
|
||
public void setBeanFactory(BeanFactory beanFactory) {
|
||
super.setBeanFactory(beanFactory);
|
||
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
|
||
throw new IllegalArgumentException(
|
||
"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
|
||
}
|
||
initBeanFactory((ConfigurableListableBeanFactory) beanFactory); //子类会继续重写
|
||
}
|
||
```
|
||
|
||
##### AnnotationAwareAspectJAutoProxyCreator#initBeanFactory()
|
||
|
||
```java
|
||
@Override // BeanFactoryAware 来的。 当前后置处理器初始化创建对象的时候回调的
|
||
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
|
||
super.initBeanFactory(beanFactory);
|
||
if (this.aspectJAdvisorFactory == null) {
|
||
//
|
||
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory); //准备一个ReflectiveAspectJAdvisorFactory
|
||
}
|
||
this.aspectJAdvisorsBuilder =
|
||
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
|
||
}
|
||
```
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211011223856339.png" />
|
||
|
||
```java
|
||
public ReflectiveAspectJAdvisorFactory(@Nullable BeanFactory beanFactory) {
|
||
this.beanFactory = beanFactory;
|
||
}
|
||
```
|
||
|
||
##### AnnotationAwareAspectJAutoProxyCreator后置处理器创建并初始化完成
|
||
|
||
> 自此AnnotationAwareAspectJAutoProxyCreator这个后置处理器的对象已经创建完成,并且已经初始化完成。后续它就**有可能**要开始参与其它Bean的创建过程了。
|
||
|
||
### createBean()里调用resolveBeforeInstantiation(),AnnotationAwareAspectJAutoProxyCreator后置处理器开始第一次发挥作用
|
||
|
||
#### Debug调用栈-调用AnnotationAwareAspectJAutoProxyCreator的isInfrastructureClass()开始参与其它Bean的创建,并判断当前Bean是不是切面
|
||
|
||
|
||
|
||
> 从createBean里调用resolveBeforeInstantiation,AnnotationAwareAspectJAutoProxyCreator开始第一次发挥作用
|
||
|
||
```java
|
||
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
|
||
throws BeanCreationException {
|
||
|
||
if (logger.isTraceEnabled()) {
|
||
logger.trace("Creating instance of bean '" + beanName + "'");
|
||
}
|
||
RootBeanDefinition mbdToUse = mbd;
|
||
|
||
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
|
||
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
|
||
mbdToUse = new RootBeanDefinition(mbd);
|
||
mbdToUse.setBeanClass(resolvedClass);
|
||
}
|
||
|
||
// Prepare method overrides.
|
||
try {
|
||
mbdToUse.prepareMethodOverrides();
|
||
}
|
||
catch (BeanDefinitionValidationException ex) {
|
||
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
|
||
beanName, "Validation of method overrides failed", ex);
|
||
}
|
||
|
||
try {
|
||
//(即使AOP的BeanPostProcessor都不会珍惜这个机会) 提前给我们一个机会,去返回组件的代理对象。 Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
|
||
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
|
||
if (bean != null) {
|
||
return bean;
|
||
}
|
||
}
|
||
catch (Throwable ex) {
|
||
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
|
||
"BeanPostProcessor before instantiation of bean failed", ex);
|
||
}
|
||
|
||
try { //Spring真正自己创建对象
|
||
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
|
||
if (logger.isTraceEnabled()) {
|
||
logger.trace("Finished creating instance of bean '" + beanName + "'");
|
||
}
|
||
return beanInstance;
|
||
}
|
||
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
|
||
throw ex;
|
||
}
|
||
catch (Throwable ex) {
|
||
throw new BeanCreationException(
|
||
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
|
||
}
|
||
}
|
||
```
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211011224506258.png"/>
|
||
|
||
1. 我们来看一下是什么时候触发的,看图中的beanName==myBeanPostProcessor时触发的,也就是创建完AnnotationAwareAspectJAutoProxyCreator,第一次创建别的后置处理器时触发的。
|
||
2. 这里虽然开始参与其它Bean的创建过程,但也可能是什么都没做。
|
||
3. AnnotationAwareAspectJAutoProxyCreator的这个isInfrastructureClass()方法主要作用就是找到当前Bean的切面是哪些,存到一个Map里,后面可能会用到
|
||
|
||
##### AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation()
|
||
|
||
```java
|
||
@Nullable
|
||
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
|
||
Object bean = null;
|
||
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
|
||
// Make sure bean class is actually resolved at this point.
|
||
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
|
||
Class<?> targetType = determineTargetType(beanName, mbd);
|
||
if (targetType != null) {
|
||
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
|
||
if (bean != null) {
|
||
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
|
||
}
|
||
}
|
||
}
|
||
mbd.beforeInstantiationResolved = (bean != null);
|
||
}
|
||
return bean;
|
||
}
|
||
|
||
@Nullable
|
||
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
|
||
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
|
||
Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
|
||
if (result != null) {
|
||
return result;
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
```
|
||
|
||
##### AbstractAutoProxyCreator#postProcessBeforeInstantiation()
|
||
|
||
```java
|
||
@Override
|
||
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
|
||
Object cacheKey = getCacheKey(beanClass, beanName);
|
||
|
||
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
|
||
if (this.advisedBeans.containsKey(cacheKey)) { //已经分析过的组件内
|
||
return null;
|
||
} //所有增强了的组件会被缓存在advisedBeans,如果我们需要增强的bean,我们就放在缓存中
|
||
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
|
||
this.advisedBeans.put(cacheKey, Boolean.FALSE);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
//创建个代理 Create proxy here if we have a custom TargetSource.
|
||
// Suppresses unnecessary default instantiation of the target bean:
|
||
// The TargetSource will handle target instances in a custom fashion.
|
||
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
|
||
if (targetSource != null) {
|
||
if (StringUtils.hasLength(beanName)) {
|
||
this.targetSourcedBeans.add(beanName);
|
||
}
|
||
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
|
||
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
|
||
this.proxyTypes.put(cacheKey, proxy.getClass());
|
||
return proxy;
|
||
}
|
||
|
||
return null;
|
||
}
|
||
```
|
||
|
||
> 注意切面都已经存在了advisedBeans这个Map里
|
||
|
||
##### AnnotationAwareAspectJAutoProxyCreator#isInfrastructureClass()找哪些是切面
|
||
|
||
```java
|
||
protected boolean isInfrastructureClass(Class<?> beanClass) {
|
||
// Previously we setProxyTargetClass(true) in the constructor, but that has too
|
||
// broad an impact. Instead we now override isInfrastructureClass to avoid proxying
|
||
// aspects. I'm not entirely happy with that as there is no good reason not
|
||
// to advise aspects, except that it causes advice invocation to go through a
|
||
// proxy, and if the aspect implements e.g the Ordered interface it will be
|
||
// proxied by that interface and fail at runtime as the advice method is not
|
||
// defined on the interface. We could potentially relax the restriction about
|
||
// not advising aspects in the future. 判断是否切面
|
||
return (super.isInfrastructureClass(beanClass) ||
|
||
(this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
|
||
}
|
||
```
|
||
|
||
##### AbstractAutoProxyCreator
|
||
|
||
```java
|
||
// 这个意思就是实现了Advice,Pointcut,Advisor,AopInfrastructureBean这些类也会把你当成是切面,不一定非要是注解
|
||
protected boolean isInfrastructureClass(Class<?> beanClass) {
|
||
boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
|
||
Pointcut.class.isAssignableFrom(beanClass) ||
|
||
Advisor.class.isAssignableFrom(beanClass) ||
|
||
AopInfrastructureBean.class.isAssignableFrom(beanClass);
|
||
if (retVal && logger.isTraceEnabled()) {
|
||
logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
|
||
}
|
||
return retVal;
|
||
}
|
||
```
|
||
|
||
##### AbstractAspectJAdvisorFactory
|
||
|
||
```java
|
||
@Override
|
||
public boolean isAspect(Class<?> clazz) {
|
||
return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
|
||
}
|
||
//这里就是判断标注了@Aspect的才是切面
|
||
private boolean hasAspectAnnotation(Class<?> clazz) {
|
||
return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
|
||
}
|
||
```
|
||
|
||
|
||
|
||
#### Debug调用栈-调用aspectJAdvisorsBuilder的findCandidateAdvisors()方法
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211011230711617.png"/>
|
||
|
||
AbstractAutoProxyCreator#postProcessBeforeInstantiation()这个方法,上面刚分析过,这次来分析shouldskip()
|
||
|
||
##### AspectJAwareAdvisorAutoProxyCreator#shouldSkip()
|
||
|
||
```java
|
||
@Override //判断是否需要跳过当前类
|
||
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
|
||
// TODO: Consider optimization by caching the list of the aspect names
|
||
List<Advisor> candidateAdvisors = findCandidateAdvisors(); //找到候选的增强器
|
||
for (Advisor advisor : candidateAdvisors) {
|
||
if (advisor instanceof AspectJPointcutAdvisor &&
|
||
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
|
||
return true;
|
||
}
|
||
}
|
||
return super.shouldSkip(beanClass, beanName);
|
||
}
|
||
```
|
||
|
||
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211011230223566.png"/>
|
||
|
||
它进去的时候就是beanName==LogAspect,我们看看它是怎么判断的
|
||
|
||
##### AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors()
|
||
|
||
```java
|
||
@Override //找到候选的增强器。
|
||
protected List<Advisor> findCandidateAdvisors() {
|
||
// Add all the Spring advisors found according to superclass rules. 判断这个bean是否需要增强只需要找到他的所有增强器
|
||
List<Advisor> advisors = super.findCandidateAdvisors();
|
||
if (this.aspectJAdvisorsBuilder != null) { //aspectJAdvisorsBuilder这个东西在上面创建aspectJAdvisorsBuilder就已经赋值了,所以这里不是null
|
||
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
|
||
}
|
||
return advisors;
|
||
}
|
||
```
|
||
|
||
我们这里先放行,看构造了哪些增强器
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211011233722352.png"/>
|
||
|
||
##### BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors()找到切面,并创建增强器advisors
|
||
|
||
1. 可能会感觉到一点奇怪,此时beanName是myBeanPostProcessor,这个时候为什么要走到这里buildAspectJAdvisors(字面翻译就是构建增强器)这个方法。
|
||
|
||
```java
|
||
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<>();
|
||
//获取容器中Object类型的组件,那意思就是获取所有组件
|
||
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
|
||
this.beanFactory, Object.class, true, false);
|
||
// for循环判断所有组件是不是切面,是的话就缓存
|
||
for (String beanName : beanNames) {
|
||
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.
|
||
Class<?> beanType = this.beanFactory.getType(beanName, false);
|
||
if (beanType == null) {
|
||
continue;
|
||
}
|
||
//
|
||
if (this.advisorFactory.isAspect(beanType)) {
|
||
aspectNames.add(beanName); //每一个组件都先判断是否是切面,如果是放在集合中
|
||
AspectMetadata amd = new AspectMetadata(beanType, beanName);
|
||
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
|
||
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;
|
||
}
|
||
```
|
||
|
||
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211011232136364.png"/>
|
||
|
||
for循环所有组件之后,有切面的话,就赋值,然后aspectNames
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211011232645429.png"/>
|
||
|
||
#### 结论
|
||
|
||
1. 最终在BeanName是myBeanPostProcessor的时候,或者说在我们创建完AnnotationAwareAspectJAutoProxyCreator这个后置处理器之后,再接着创建下一个组件的时候。createBean()里调用resolveBeforeInstantiation(),AnnotationAwareAspectJAutoProxyCreator后置处理器开始第一次发挥作用,提前就把切面的名字找到了logAspect,并且找到了这个logAspect切面的4个增强器。
|
||
2. 具体构建增强器的过程下面马上会讲,讲之前再看一个问题
|
||
|
||
|
||
|
||
#### isInfrastructureClass()和shouldSkip()区别
|
||
|
||
AbstractAutoProxyCreator
|
||
|
||
```java
|
||
@Override
|
||
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
|
||
Object cacheKey = getCacheKey(beanClass, beanName);
|
||
|
||
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
|
||
if (this.advisedBeans.containsKey(cacheKey)) { //已经分析过的组件内
|
||
return null;
|
||
} //所有增强了的组件会被缓存在advisedBeans,如果我们需要增强的bean,我们就放在缓存中
|
||
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
|
||
this.advisedBeans.put(cacheKey, Boolean.FALSE);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
//创建个代理 Create proxy here if we have a custom TargetSource.
|
||
// Suppresses unnecessary default instantiation of the target bean:
|
||
// The TargetSource will handle target instances in a custom fashion.
|
||
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
|
||
if (targetSource != null) {
|
||
if (StringUtils.hasLength(beanName)) {
|
||
this.targetSourcedBeans.add(beanName);
|
||
}
|
||
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
|
||
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
|
||
this.proxyTypes.put(cacheKey, proxy.getClass());
|
||
return proxy;
|
||
}
|
||
|
||
return null;
|
||
}
|
||
```
|
||
|
||
1. 在前面讲isInfrastructureClass()的时候,我们发现它会找当前Bean的切面,并判断当前Bean是不是切面。如果当前Bean是切面,那么就不会走shouldSkip,直接放到advisedBeans这个Map里。比如当这里的beanName是logAspect的时候,就直接放到advisedBeans里。
|
||
2. 放到advisedBeans的作用就是后面在进行代理的时候,会跳过logAspect本身。
|
||
3. 如果当前bean不是切面,才会走shouldSkip,不过shouldSkip里for循环分析的是所有的bean,找哪些是切面
|
||
|
||
### 构建增强器的过程
|
||
|
||
我们再来看下构建增强器的具体过程
|
||
|
||
#### BeanactoryAspectJAdvisorsBuilder#buildAspectJAdvisors真正开始构建增强器
|
||
|
||
```java
|
||
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<>();
|
||
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
|
||
this.beanFactory, Object.class, true, false);
|
||
for (String beanName : beanNames) {
|
||
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.
|
||
Class<?> beanType = this.beanFactory.getType(beanName, false);
|
||
if (beanType == null) {
|
||
continue;
|
||
}
|
||
//这里也判断了一次,循环的beanName是否是切面
|
||
if (this.advisorFactory.isAspect(beanType)) {
|
||
aspectNames.add(beanName); //每一个组件都先判断是否是切面,如果是放在集合中
|
||
AspectMetadata amd = new AspectMetadata(beanType, beanName);
|
||
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
|
||
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;
|
||
}
|
||
```
|
||
|
||
|
||
|
||
#### ReflectiveAspectJAdvisorFactory#getAdvisors()找到切面里面定义的所有增强器
|
||
|
||
增强器就是@before,@after这些标注的
|
||
|
||
```java
|
||
@Override //找到切面里面定义的所有增强器
|
||
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
|
||
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
|
||
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
|
||
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 ArrayList<>(); //收集所有增强器
|
||
// 从切面类获取增强方法
|
||
for (Method method : getAdvisorMethods(aspectClass)) {
|
||
// Prior to Spring Framework 5.2.7, advisors.size() was supplied as the declarationOrderInAspect
|
||
// to getAdvisor(...) to represent the "current position" in the declared methods list.
|
||
// However, since Java 7 the "current position" is not valid since the JDK no longer
|
||
// returns declared methods in the order in which they are declared in the source code.
|
||
// Thus, we now hard code the declarationOrderInAspect to 0 for all advice methods
|
||
// discovered via reflection in order to support reliable advice ordering across JVM launches.
|
||
// Specifically, a value of 0 aligns with the default value used in
|
||
// AspectJPrecedenceComparator.getAspectDeclarationOrder(Advisor). //分析如果当前方法是通知方法则封装为Advisor
|
||
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, 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()) {
|
||
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
|
||
advisors.add(0, instantiationAdvisor);
|
||
}
|
||
|
||
// 需要增强的属性: 主要针对@DeclareParents ; Find introduction fields.
|
||
for (Field field : aspectClass.getDeclaredFields()) {
|
||
Advisor advisor = getDeclareParentsAdvisor(field);
|
||
if (advisor != null) {
|
||
advisors.add(advisor);
|
||
}
|
||
}
|
||
|
||
return advisors;
|
||
}
|
||
|
||
|
||
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
|
||
List<Method> methods = new ArrayList<>(); //methods.add(method)
|
||
ReflectionUtils.doWithMethods(aspectClass, methods::add, adviceMethodFilter);
|
||
if (methods.size() > 1) {
|
||
methods.sort(adviceMethodComparator);
|
||
}
|
||
return methods;
|
||
}
|
||
|
||
```
|
||
|
||
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012113939403.png"/>
|
||
|
||
|
||
|
||
|
||
|
||
#### ReflectionUtils
|
||
|
||
```java
|
||
public static void doWithMethods(Class<?> clazz, MethodCallback mc, @Nullable MethodFilter mf) {
|
||
// Keep backing up the inheritance hierarchy. 获取所有方法
|
||
Method[] methods = getDeclaredMethods(clazz, false);
|
||
// 下面的for循环只是收集clazz里的所有方法,不做任何过滤
|
||
for (Method method : methods) {
|
||
if (mf != null && !mf.matches(method)) {
|
||
continue;
|
||
}
|
||
try {
|
||
// 这里就是回调上面的methods::add,也就是list的add方法,给methods里面添加东西
|
||
mc.doWith(method);
|
||
}
|
||
catch (IllegalAccessException ex) {
|
||
throw new IllegalStateException("Not allowed to access method '" + method.getName() + "': " + ex);
|
||
}
|
||
}
|
||
//
|
||
if (clazz.getSuperclass() != null && (mf != USER_DECLARED_METHODS || clazz.getSuperclass() != Object.class)) {
|
||
// 这里就是继续调用此方法获取父类的方法
|
||
doWithMethods(clazz.getSuperclass(), mc, mf);
|
||
}
|
||
else if (clazz.isInterface()) {
|
||
for (Class<?> superIfc : clazz.getInterfaces()) {
|
||
doWithMethods(superIfc, mc, mf);
|
||
}
|
||
}
|
||
}
|
||
// 这应该是判断是不是桥接方法,合成方法什么的。具体我也不太懂
|
||
public static final MethodFilter USER_DECLARED_METHODS = (method -> !method.isBridge() && !method.isSynthetic());
|
||
```
|
||
|
||
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012115005897.png"/>
|
||
|
||
|
||
|
||
获取父类的方法
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012115205531.png"/>
|
||
|
||
然后回到这里
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012142115626.png"/>
|
||
|
||
最后回到这个for循环,循环所有的方法
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012142802483.png"/>
|
||
|
||
#### ReflectiveAspectJAdvisorFactory#getAdvisor()
|
||
|
||
```java
|
||
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
|
||
int declarationOrderInAspect, String aspectName) {
|
||
|
||
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
|
||
|
||
AspectJExpressionPointcut expressionPointcut = getPointcut(
|
||
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
|
||
if (expressionPointcut == null) {
|
||
return null;
|
||
}
|
||
|
||
// 将信息都封装成Advisor实现类
|
||
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]);
|
||
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
|
||
if (this.beanFactory != null) {
|
||
ajexp.setBeanFactory(this.beanFactory);
|
||
}
|
||
return ajexp;
|
||
}
|
||
```
|
||
|
||
|
||
|
||
#### AbstractAspectJAdvisorFactory
|
||
|
||
```java
|
||
private static final Class<?>[] ASPECTJ_ANNOTATION_CLASSES = new Class<?>[] {
|
||
Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class};
|
||
|
||
@Nullable
|
||
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
|
||
for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
|
||
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
|
||
if (foundAnnotation != null) {
|
||
return foundAnnotation;
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
```
|
||
|
||
可以看到就是解析了注解
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
### createBean()里调用doCreateBean(),AnnotationAwareAspectJAutoProxyCreator开始第二次发挥作用
|
||
|
||
```java
|
||
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
|
||
throws BeanCreationException {
|
||
|
||
if (logger.isTraceEnabled()) {
|
||
logger.trace("Creating instance of bean '" + beanName + "'");
|
||
}
|
||
RootBeanDefinition mbdToUse = mbd;
|
||
|
||
|
||
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
|
||
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
|
||
mbdToUse = new RootBeanDefinition(mbd);
|
||
mbdToUse.setBeanClass(resolvedClass);
|
||
}
|
||
|
||
// Prepare method overrides.
|
||
try {
|
||
mbdToUse.prepareMethodOverrides();
|
||
}
|
||
catch (BeanDefinitionValidationException ex) {
|
||
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
|
||
beanName, "Validation of method overrides failed", ex);
|
||
}
|
||
|
||
try {
|
||
//(即使AOP的BeanPostProcessor都不会珍惜这个机会) 提前给我们一个机会,去返回组件的代理对象。 Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
|
||
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
|
||
if (bean != null) {
|
||
return bean;
|
||
}
|
||
}
|
||
catch (Throwable ex) {
|
||
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
|
||
"BeanPostProcessor before instantiation of bean failed", ex);
|
||
}
|
||
|
||
try { //Spring真正自己创建对象
|
||
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
|
||
if (logger.isTraceEnabled()) {
|
||
logger.trace("Finished creating instance of bean '" + beanName + "'");
|
||
}
|
||
return beanInstance;
|
||
}
|
||
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
|
||
|
||
throw ex;
|
||
}
|
||
catch (Throwable ex) {
|
||
throw new BeanCreationException(
|
||
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
|
||
}
|
||
}
|
||
```
|
||
|
||
#### Debug调用栈
|
||
|
||
继续放行debug
|
||
|
||
到了初始化这里了,说明前面无参构造创建myBeanPostProcessor对象已经完成了
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211011233400056.png"/>
|
||
|
||
#### AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors()
|
||
|
||
又来到了这个方法
|
||
|
||
```java
|
||
protected List<Advisor> findCandidateAdvisors() {
|
||
// Add all the Spring advisors found according to superclass rules. 判断这个bean是否需要增强只需要找到他的所有增强器
|
||
List<Advisor> advisors = super.findCandidateAdvisors();
|
||
// 我不需要增强,难道还要给我构建增强器???? Build Advisors for all AspectJ aspects in the bean factory.
|
||
if (this.aspectJAdvisorsBuilder != null) { //增强器的构建器只要有
|
||
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
|
||
}
|
||
return advisors;
|
||
}
|
||
```
|
||
|
||
|
||
|
||
我们这里先放行,看构造了哪些增强器
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211011233722352.png"/>
|
||
|
||
#### BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors()
|
||
|
||
在这个resolveBeforeInstantiation()方法里,我们已经把aspectNames找到了,aspectNames!=null,就不走第一个if了
|
||
|
||
然后又再次来到了这个方法,开始在这里构造增强器了
|
||
|
||
```java
|
||
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<>();
|
||
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
|
||
this.beanFactory, Object.class, true, false);
|
||
for (String beanName : beanNames) {
|
||
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.
|
||
Class<?> beanType = this.beanFactory.getType(beanName, false);
|
||
if (beanType == null) {
|
||
continue;
|
||
}
|
||
if (this.advisorFactory.isAspect(beanType)) {
|
||
aspectNames.add(beanName); //每一个组件都先判断是否是切面,如果是放在集合中
|
||
AspectMetadata amd = new AspectMetadata(beanType, beanName);
|
||
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
|
||
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就不走了,直接跳到这里
|
||
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;
|
||
}
|
||
```
|
||
|
||
#### 结论
|
||
|
||
|
||
> 1. registerBeanPostProcessors自此干完活了,后面就要走下面的代码了,创建其它Bean(也就是非后置处理器的这Bean)。我们重点看切入点HelloService和切面logAspect怎么创建的
|
||
> 2. 注意,前面只是利用反射先分析准备好所有的信息,切面对象logAspect都没有创建
|
||
|
||
|
||
|
||
|
||
|
||
```java
|
||
//【大核心】bean创建;完成 BeanFactory 初始化。(工厂里面所有的组件都好了)
|
||
finishBeanFactoryInitialization(beanFactory);
|
||
```
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012153225770.png" />
|
||
|
||
### 创建HelloService代理对象之前的工作
|
||
|
||
#### 创建对象
|
||
|
||
我们在诸如下面的地方打上条件断点`beanName.equals("helloService") || beanName.equals("logAspect")`
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012153646657.png"/>
|
||
|
||
debug放行
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012154005700.png"/>
|
||
|
||
|
||
|
||
往下走进入getBean()
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012154205498.png"/>
|
||
|
||
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012154413318.png" />
|
||
|
||
走到熟悉的createbean
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012155231730.png"/>
|
||
|
||
我们以前讲过resolveBeforeInstantiation是返回代理对象的机会,我们现在来看一下AOP有没有在这里给helloService返回代理对象。F7进入此方法
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
```java
|
||
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
|
||
Object bean = null;
|
||
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
|
||
// Make sure bean class is actually resolved at this point.
|
||
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
|
||
Class<?> targetType = determineTargetType(beanName, mbd);
|
||
if (targetType != null) {
|
||
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
|
||
if (bean != null) {
|
||
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
|
||
}
|
||
}
|
||
}
|
||
mbd.beforeInstantiationResolved = (bean != null);
|
||
}
|
||
return bean;
|
||
}
|
||
```
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012160014471.png"/>
|
||
|
||
这是有一个负责AOP功能的后置处理器,就是我们前面说的那个
|
||
|
||
当循环到这个后置处理器的时候,我们进入方法
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012161510441.png"/>
|
||
|
||
|
||
|
||
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012161817522.png"/>
|
||
|
||
|
||
|
||
我debug完之后发现前置过程啥也没干,返回了个NULL。什么都没干的原因就是**负责AOP功能的后置处理器第一次运行准备好数据**和**构建增强器**这两步已经干过了
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012162158546.png"/>
|
||
|
||
|
||
|
||
|
||
|
||
1. 最后我们惊奇的发现,AOP的后置处理器在resolveBeforeInstantiation这一步竟然没有返回代理对象,这可能跟大部分人想的有出入。
|
||
2. 想一下为什么没有返回代理对象?走到这一步的时候,咱们的HelloService对象都还没有创建,更没有赋值,初始化。你如果在这里直接返回代理对象,那假设HelloService还注入了其它组件,那你返回的代理对象不就没有这些组件了嘛?直接跳过了。
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012163220063.png"/>
|
||
|
||
往下走,创建一个最原始的对象
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012165217922.png" />
|
||
|
||
#### 赋值
|
||
|
||
|
||
|
||
往下走进入赋值环节
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012165702336.png" />
|
||
|
||
我们来看下AOP的后置处理器在这一步有没有做事
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012165933421.png"/>
|
||
|
||
啥事没干,直接返回
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012170025142.png"/>
|
||
|
||
|
||
|
||
最后debug发现,整个赋值环节,AOP的后置处理器介入了,但是什么事都没干
|
||
|
||
|
||
|
||
#### 初始化
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012170944132.png"/>
|
||
|
||
进入之后发现,AOP的后置处理器在此介入了,我们再进去看下到底做了啥
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012171702722.png"/>
|
||
|
||
啥也没做,直接返回原生Bean
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012171813664.png" />
|
||
|
||
|
||
|
||
1. 我Debug的时候也很吃惊,初始化的时候applyBeanPostProcessorsBeforeInitialization也没有返回代理对象,那到底何时返回的呢?
|
||
2. 前置初始化没有做事,那我们看后置的初始化applyBeanPostProcessorsAfterInitialization
|
||
|
||
##### applyBeanPostProcessorsAfterInitialization后置初始化方法
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012172107405.png" />
|
||
|
||
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012172308103.png"/>
|
||
|
||
F7进入方法
|
||
|
||
##### AbstractAutoProxyCreator#postProcessAfterInitialization()
|
||
|
||
> 终于干活了
|
||
|
||
```java
|
||
@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;
|
||
}
|
||
|
||
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
|
||
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
|
||
return bean;
|
||
}
|
||
// 前面说的advisedBeans在这里会干活了,如果此时beanName是logAspect,这里会直接返回,不会走下面的代理逻辑,
|
||
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;
|
||
}
|
||
|
||
//如果有切面的通知方法切入这个对象,就给对象创建代理 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;
|
||
}
|
||
```
|
||
|
||
|
||
|
||
##### AbstractAdvisorAutoProxyCreator#findEligibleAdvisors()是否有切面切入这个bean
|
||
|
||
```java
|
||
@Override
|
||
@Nullable
|
||
protected Object[] getAdvicesAndAdvisorsForBean(
|
||
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
|
||
//找到所有合适这个类的 Advisor
|
||
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;
|
||
}
|
||
|
||
protected List<Advisor> findAdvisorsThatCanApply(
|
||
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
|
||
|
||
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
|
||
try {
|
||
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
|
||
}
|
||
finally {
|
||
ProxyCreationContext.setCurrentProxiedBeanName(null);
|
||
}
|
||
}
|
||
```
|
||
|
||
我发现他调用了咱们之前讲过的方法
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012173003595.png" />
|
||
|
||
因为之前调用过,缓存中有,直接返回
|
||
|
||
|
||
|
||
##### AopUtils#findAdvisorsThatCanApply()正则解析切面表达式判断是否能切入
|
||
|
||
```java
|
||
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;
|
||
}
|
||
if (canApply(candidate, clazz, hasIntroductions)) {
|
||
eligibleAdvisors.add(candidate);
|
||
}
|
||
}
|
||
return eligibleAdvisors;
|
||
}
|
||
|
||
|
||
|
||
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;
|
||
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
|
||
}
|
||
else {
|
||
// It doesn't have a pointcut so we assume it applies.
|
||
return true;
|
||
}
|
||
}
|
||
```
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012173631784.png"/>
|
||
|
||
|
||
|
||
```java
|
||
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
|
||
Assert.notNull(pc, "Pointcut must not be null");
|
||
if (!pc.getClassFilter().matches(targetClass)) {
|
||
return false;
|
||
}
|
||
|
||
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<>();
|
||
if (!Proxy.isProxyClass(targetClass)) {
|
||
classes.add(ClassUtils.getUserClass(targetClass));
|
||
}
|
||
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
|
||
|
||
for (Class<?> clazz : classes) {
|
||
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
|
||
for (Method method : methods) {
|
||
//下面就是正则解析的流程了,不细讲了
|
||
if (introductionAwareMethodMatcher != null ?
|
||
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
|
||
methodMatcher.matches(method, targetClass)) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
```
|
||
|
||
##### 返回到AbstractAdvisorAutoProxyCreator#findEligibleAdvisors()
|
||
|
||
接着我们返回到这一步,看到了这几个增强器
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012174251200.png" />
|
||
|
||
这里又有一个重要方法
|
||
|
||
##### AspectJAwareAdvisorAutoProxyCreator#extendAdvisors()
|
||
|
||
```java
|
||
protected void extendAdvisors(List<Advisor> candidateAdvisors) {
|
||
AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
|
||
}
|
||
```
|
||
|
||
##### AspectJProxyUtils#makeAdvisorChainAspectJCapableIfNecessary()创建增强器链
|
||
|
||
```java
|
||
//创建增强器链
|
||
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;
|
||
}
|
||
} //链里面添加了个ExposeInvocationInterceptor(拦截器)
|
||
if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) {
|
||
advisors.add(0, ExposeInvocationInterceptor.ADVISOR);
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
```
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012174626015.png" />
|
||
|
||
回到AbstractAutoProxyCreator#wrapIfNecessary,调用下面的方法真正开始创建代理对象
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012191915487.png"/>
|
||
|
||
##### AbstractAutoProxyCreator#createProxy()开始创建代理对象
|
||
|
||
```java
|
||
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()) {
|
||
if (shouldProxyTargetClass(beanClass, beanName)) {
|
||
proxyFactory.setProxyTargetClass(true);
|
||
}
|
||
else {
|
||
evaluateProxyInterfaces(beanClass, proxyFactory);
|
||
}
|
||
}
|
||
//构建增强器
|
||
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());
|
||
}
|
||
```
|
||
|
||
##### ProxyFactory#getProxy()
|
||
|
||
```java
|
||
public Object getProxy(@Nullable ClassLoader classLoader) {
|
||
return createAopProxy().getProxy(classLoader);
|
||
}
|
||
```
|
||
|
||
|
||
|
||
##### ProxyCreatorSupport#createAopProxy()
|
||
|
||
```java
|
||
protected final synchronized AopProxy createAopProxy() {
|
||
if (!this.active) {
|
||
activate();
|
||
}
|
||
return getAopProxyFactory().createAopProxy(this);
|
||
}
|
||
```
|
||
|
||
##### DefaultAopProxyFactory#createAopProxy()
|
||
|
||
```java
|
||
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
|
||
if (!NativeDetector.inNativeImage() &&
|
||
(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.");
|
||
}
|
||
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
|
||
return new JdkDynamicAopProxy(config);
|
||
}
|
||
return new ObjenesisCglibAopProxy(config);
|
||
}
|
||
else {
|
||
return new JdkDynamicAopProxy(config);
|
||
}
|
||
}
|
||
```
|
||
|
||
要么是cglib的代理要么是jdk的代理
|
||
|
||
##### CglibAopProxy#getProxy()
|
||
|
||
```java
|
||
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;
|
||
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...
|
||
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 ClassLoaderAwareGeneratorStrategy(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);
|
||
}
|
||
}
|
||
```
|
||
|
||
##### HelloService代理对象创建完成
|
||
|
||
|
||
|
||
最后返回
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012193828795.png" />
|
||
|
||
|
||
|
||
继续返回
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012194036836.png"/>
|
||
|
||
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012194217705.png"/>
|
||
|
||
最终单例池里就有代理对象了
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012194446377.png"/>
|
||
|
||
##### logAspect创建原生对象,而不是代理对象
|
||
|
||
logAspect切面对象最后创建的是原生对象,如下图,因为他不需要代理
|
||
|
||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_06/image-20211012194718066.png" />
|
||
|
||
|
||
|
||
> 自此,负责AOP的后置处理器和代理对象创建过程讲完了,下一章讲AOP执行流程。
|