Spring5.X源码分析(IOC/AOP)

Spring基础

  • @Configuration

      标注在类上,相当于Spring XML配置文件中的标签,用来配置Spring容器上下文。例如:初始化数据源实例。
  • @ComponentScan
      标注在类上,主要负责扫描配置组件并将其注入IOC,与@Configuration一起使用。
    通过其includeFilters属性指定特定注解生效,excludeFilters指定排除注解,使其失效。
@ComponentScan(value = "com.lmx", includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Controller.class)}, useDefaultFilters = false)
  • @Scope
      指定容器中实例的作用域,取值于singleton、prototype、request1、session2,默认singleton。
  • @Lazy
      指定容器中实例是否启用延迟加载,默认取值为false,不用则不适用@Lazy标注。
  • @Condition
      Spring4.0 增加的条件注解,通过该注解可实现Bean实例的选择性注入。例如,针对Win7系统转配Win7配置的业务。
  • @PropertySource
      加载指定的属性文件。例如,@PropertySource(value= {“classpath:config/jdbc-dev.properties”},ignoreResourceNotFound=false,encoding=“UTF-8”,name=“jdbc-dev.properties”)
  • @Import
      用来整合所有在@Configuration注解中定义的bean配置,相当于将单个配置实例导入到IOC中。
  • @ImportResource
      加载指定XML配置文件,可以与@Import实现注解和XML的混合配置。
  • BeanDefinition API
      Spring Bean实例的原型,存储IOC实例的相关信息,例如作用域、是否开启延迟加载、实例名称等。
  • ImportSelector API
      是spring中导入外部配置的核心接口,在SpringBoot的自动化配置和@EnableXXX(功能性注解)都有它的存在。
  • ImportBeanDefinitionRegistrar API
      该接口可实现Bean实例的手动/动态注册。例如,Feign的启动注解@EnableFeignClients中通过@Import导入了FeignClientsRegistrar,其集成自ImportBeanDefinitionRegistrar,通过此API完成默认配置的加载工作。
	public void registerBeanDefinitions(AnnotationMetadata metadata,
			BeanDefinitionRegistry registry) {
		registerDefaultConfiguration(metadata, registry);
		registerFeignClients(metadata, registry);
	}

`

  • BeanFactory
      对象工厂/IOC容器。Spring中所有对象实例都交由BeanFactory进行管理。

  • FactoryBean
      一个Bean实例,但又不同于普通实例,是能够生产并修饰Bean实例的工厂实例,是工厂模式和装饰器模式结合的产物。

  • BeanFactoryAware API
      实现了BeanFactoryAware接口的bean,可以直接通过beanfactory来访问spring的容器。

环境搭建

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.0.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.0.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.11</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.66</version>
        </dependency>

        <!-- mysql 依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>

·

@Data
public class UserEntity {
    private Integer userId;
    private String userName;

    public UserEntity(Integer userId, String userName) {
        this.userId = userId;
        this.userName = userName;
    }
}
@Configuration
@ComponentScan(value = {"com.lming"})
public class MySpringConfig {
    @Bean
    public UserEntity userEntity() {
        return new UserEntity(1, "zhangsan");
    }
}
public class TestMain {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(MySpringConfig.class);
        
        System.out.println("------->>>>打印所有IOC中的实例");
        String[] beanDefinitionNames = context.getBeanDefinitionNames();
        for (String name : beanDefinitionNames) {
            System.out.println(name);
        }
        
        UserEntity userEntity = context.getBean("userEntity", UserEntity.class);
        System.out.println("获取到实例:" + userEntity);
    }
}

IOC源码分析

  Spring将IOC的加载分为三个阶段。初始化阶段加载基础环境,注册阶段注入一个或多个注解类到IOC,刷新上下文阶段进行扫包刷新配置信息,若IOC容器已存在,则销毁注册阶段创建的IOC容器,重新创建容器,完成容器初始化工作。

	public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		// 1.初始化阶段
		this();
		// 2.注册阶段
		register(annotatedClasses);
		// 3.刷新上下文阶段
		refresh();
	}

初始化阶段

  初始化阶段完成读取器扫描器的加载。

	public AnnotationConfigApplicationContext() {
		// 注解实例读取器
		this.reader = new AnnotatedBeanDefinitionReader(this);
		// 类扫描器
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

`

注解读取器(AnnotatedBeanDefinitionReader)

  调用链
	
	public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
		// getOrCreateEnvironment获取运行环境信息
		this(registry, getOrCreateEnvironment(registry));
	}
	
——> public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		Assert.notNull(environment, "Environment must not be null");
		this.registry = registry;
		this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}
	
——> public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
		registerAnnotationConfigProcessors(registry, null);
	}

  registerAnnotationConfigProcessors()中将注解处理器加载到IOC中,比如@Configuration、@Autowired、BeanFactory的驱动处理器等。

		// 省略部分代码……
		// 初始化2 - 比如@Configuration注解的驱动处理器
		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// 初始化3 - 比如@Autowired注解的驱动处理器
		if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}
	// 省略部分代码……

类扫描器(ClassPathBeanDefinitionScanner)

  类扫描器初始化工作包括三部分,注入过滤器、环境变量、加载类资源。

  调用链
	public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
		this(registry, true);
	}
	
——>	public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
		// getOrCreateEnvironment获取运行环境信息
		this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
	}
	
——>	public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
			Environment environment) {

		this(registry, useDefaultFilters, environment,
				(registry instanceof ResourceLoader ? (ResourceLoader) registry : null));
	}
	
——>	public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
			Environment environment, @Nullable ResourceLoader resourceLoader) {

		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		this.registry = registry;

		if (useDefaultFilters) {
			// 初始化4.1 - 注册默认过滤器(@Service @Controller @Repostory @Component全靠这里,includeFilters指定装载那些实例)
			registerDefaultFilters();
		}
		// 初始化4.2 - 装载系统环境配置,比如os.name,系统版本win7/10等
		setEnvironment(environment);
		// 初始化4.3 - 装载资源加载器,主要用来在程序内加载一些外部资源文件
		setResourceLoader(resourceLoader);
	}

  在registerDefaultFilters()中会注册一个默认的过滤器,与@ComponentScan注解配置includeFilters息息相关。

	protected void registerDefaultFilters() {
		this.includeFilters.add(new AnnotationTypeFilter(Component.class));
		ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
		try {
			this.includeFilters.add(new AnnotationTypeFilter(
					((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
			logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
		}
		catch (ClassNotFoundException ex) {
			// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
		}
		try {
			this.includeFilters.add(new AnnotationTypeFilter(
					((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
			logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
		}
		catch (ClassNotFoundException ex) {
			// JSR-330 API not available - simply skip.
		}
	}

初始化阶段总结

  初始阶段完成后,我们将得到一个具备处理关键注解、获取系统环境信息、可加载外部资源的应用程序上下文对象AnnotationConfigApplicationContext。

  结构图

Spring5.X源码分析(IOC/AOP)_第1张图片

注册阶段

  注册阶段通过初始化的注解读取器向上下文中注入一个或多个配置类实例,配置类优先于其他实例加载,使后续规则得以应用。例如:MySpringConfig。

  调用链
	public void register(Class<?>... componentClasses) {
		Assert.notEmpty(componentClasses, "At least one component class must be specified");
		this.reader.register(componentClasses);
	}
	
——>	public void register(Class<?>... componentClasses) {
		// 依次解析配置
		for (Class<?> componentClass : componentClasses) {
			registerBean(componentClass);
		}
	}
	
——>	public void registerBean(Class<?> beanClass) {
		doRegisterBean(beanClass, null, null, null);
	}
	
	// 核心注册逻辑
——>	<T> void doRegisterBean(Class<T> beanClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
		// 注册1 - 解析@Configuration,将注解装换为实例,注册到IOC
		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
		// 注册1.1 - 执行Bean过滤规则@Conditional
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
			return;
		}

		// 注册1.2 - 指定创建 bean 实例的回调方法,此时为 null
		abd.setInstanceSupplier(instanceSupplier);
		// 解析bean作用域(单例或者原型),如果有@Scope注解,则解析@Scope,没有则默认为singleton 
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
		// 作用域写回BeanDefinition数据结构, abd中缺损的情况下为空,将默认值singleton重新赋值到abd
		abd.setScope(scopeMetadata.getScopeName());
		// 生成bean配置类beanName
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

		// 注册1.3 - 通用注解解析到abd结构中,主要是处理Lazy, primary DependsOn, Role ,Description这五个注解
		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
		if (qualifiers != null) {
			for (Class<? extends Annotation> qualifier : qualifiers) {
				// 如果配置@Primary注解,则设置当前Bean为自动装配autowire时首选bean
				if (Primary.class == qualifier) {
					abd.setPrimary(true);
				}
				// 设置当前bean为延迟加载
				else if (Lazy.class == qualifier) {
					abd.setLazyInit(true);
				}
				// 其他注解,则添加到abd结构中
				else {
					abd.addQualifier(new AutowireCandidateQualifier(qualifier));
				}
			}
		}
		for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
			customizer.customize(abd);
		}

		// 注册1.4 - 根据Bean名称和BeanDefinition创建一个Holder,Holder是二者的映射对象
		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}

——> public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		// 获取主选项的实例名称.
		String beanName = definitionHolder.getBeanName();
		// 注册1.5 - 将BeanDefinition注入到IOC容器(所有实例都将被封装为BeanDefinition)
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

		// (如果有)注册次级选项bean名称的别名。
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}

  IDEA Ctrl+ALT+B查看BeanDefinitionRegistry API的DefaultListableBeanFactory的注册实现:

	public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {
		// 省略部分代码……
		if (existingDefinition != null) {
		// 省略部分代码……
		// 注册1.6 - Spring使用ConcurrentHashMap保存BeanDefinition
			this.beanDefinitionMap.put(beanName, beanDefinition);
		}
		else {
		// 省略部分代码……
		}
	}

  查看beanDefinitionMap,是ConcurrentHashMap的BeanDefinition集合,故我们可以得知IOC默认是采用ConcurrentHashMap存储实例。

注册阶段总结

  • 重点完成了bean配置类本身的解析和注册,主要是一些注解信息;
  • Bean实例作用域、延迟加载、主从等注解处理;
  • 最后使用ConcurrentHashMap存储实例。
  结构图

Spring5.X源码分析(IOC/AOP)_第2张图片
`

刷新上下文阶段

  刷新上下文阶段是对整个Spring框架是至关重要的,同时也非常的复杂。这里只专注于联合研究IOC与AOP,因此省略其他部分的内容。

  • 扫包并执行BeanFactory后置处理器(invokeBeanFactoryPostProcessors)
  • 注册拦截Bean的相关处理器(registerBeanPostProcessors)
  • 实例化所有剩余的单例Bean(非延迟初始化)(finishBeanFactoryInitialization)
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// 刷新前的预处理
			prepareRefresh();
			// 获取刷新后的内部Bean工厂
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
			// BeanFactory的预准备工作
			prepareBeanFactory(beanFactory);

			try {
				// BeanFactory准备工作完成后,可以做一些后置处理工作,空方法,用于在容器的子类中扩展
				postProcessBeanFactory(beanFactory);
				// 刷新上下文1.1.1 - 执行BeanFactory后置处理器 ,在IOC初始化后实例构造方法之前执行
				invokeBeanFactoryPostProcessors(beanFactory);
				// 刷新上下文1.2.1 - 注册拦截Bean的相关处理器,这是实现AOP的核心
				registerBeanPostProcessors(beanFactory);
				// 初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
				initMessageSource();
				// 初始化事件派发器
				initApplicationEventMulticaster();
				// 空方法,可以用于子类实现在容器刷新时自定义逻辑
				onRefresh();
				// 注册时间监听器,将所有项目里面的ApplicationListener注册到容器中来
				registerListeners();
				// 刷新上下文1.3.1 - 实例化所有剩余的单例Bean(非延迟初始化)。
				finishBeanFactoryInitialization(beanFactory);
				// 完成BeanFactory的初始化创建工作,IOC容器就创建完成;
				finishRefresh();
			}
			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " 
							"cancelling refresh attempt: " + ex);
				}
				// 销毁已创建的单例以避免资源悬空。
				destroyBeans();
				// 重置'active' 旗帜.
				cancelRefresh(ex);
				throw ex;
			}
			finally {
				// 重置Spring核心中的常见自省缓存,因为我们 //可能不再需要单例bean的元数据...
				resetCommonCaches();
			}
		}
	}

刷新上下文阶段 - 调用BeanFactory后置处理器

  作用:允许我们在工厂里所有的bean被加载进来后但是还没初始化前,对所有bean的属性进行修改也可以add属性值。
  执行时机:在IOC初始化后实例构造方法之前执行。

  环境搭建
在MySpringConfig类上添加:@Import({MyBeanFactoryPostProcessor.class})

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
        System.out.println("BeanFactory后置处理器,筛选所有Bean实例中名称为“payEntity”的实例,并将其amount改为500");
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println("当前迭代实例------>>>" + beanDefinitionName);
            if (beanDefinitionName.equals("payEntity")) {
                BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanDefinitionName);
                System.out.println("开始修改,对象原属性值为:" + JSON.toJSONString(beanDefinition.getPropertyValues()));
                beanDefinition.getPropertyValues().add("amount", "500");
                System.out.println("修改后,对象原属性值为:" + JSON.toJSONString(beanDefinition.getPropertyValues()));
                return;
            }
        }
    }
}
源码分析

  我将BeanFactory后处理器分为两步进行分析,注册以及执行

注册(Spring 扫包)

  我们回到刷新上下文阶段 invokeBeanFactoryPostProcessors(beanFactory)阶段,官方给定的解释是:

Instantiate and invoke all registered BeanFactoryPostProcessor beans,respecting explicit order if given.

  翻译过来就是:实例化并调用所有已注册的BeanFactoryPostProcessor,(如果给定的话)遵循显式顺序。也就是说注册和执行皆由invokeBeanFactoryPostProcessors完成,它是至关重要的。

  调用链
	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
		// 省略部分代码……
	}
	// invokeBeanFactoryPostProcessors代码比较长,这里只贴关键代码
——> public static void invokeBeanFactoryPostProcessors(
		// 省略部分代码…… 这部分代码主要是对BeanDefinitionRegistryPostProcessor进行排序
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// 1、首先,调用PriorityOrdered接口实现,其拥有调用最高优先级;
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// 2、然后,调用Ordered接口实现,我们写的MyBeanFactoryPostProcessor不在这两个层次;
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// 3、最后, 调用其他BeanDefinitionRegistryPostProcessors.
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					if (!processedBeans.contains(ppName)) {
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						reiterate = true;
					}
				}
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				currentRegistryProcessors.clear();
			}
			// 省略BeanFactory后置处理器执行部分代码…… 
			// 我们重点关注invokeBeanDefinitionRegistryPostProcessors的调用
	}
——> private static void invokeBeanDefinitionRegistryPostProcessors(
			Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {

		for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
			postProcessor.postProcessBeanDefinitionRegistry(registry);
		}
	}

  IDEA快捷键Ctrl+Alt+B查看postProcessBeanDefinitionRegistry实现,默认只有ConfigurationClassPostProcessor。我们继续查看其postProcessBeanDefinitionRegistry的调用链,解析注册过程:

	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
		int registryId = System.identityHashCode(registry);
		// 省略部分日志代码……
		this.registriesPostProcessed.add(registryId);
		processConfigBeanDefinitions(registry);
	}
	
	// 这里是Spring 扫包的入口
——> public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
		List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
		String[] candidateNames = registry.getBeanDefinitionNames();

		for (String beanName : candidateNames) {
			BeanDefinition beanDef = registry.getBeanDefinition(beanName);
			if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
					ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
				}
			}
			// checkConfigurationClassCandidate检索IOC中所有的@Configuration注解类,到这一步为止IOC中只有一个@Configuration注解类他就是我们自定义的MySpringConfig,在注册阶段注入IOC。
			else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
				configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
			}
		}
		// 如果未找到@Configuration类,则立即返回
		if (configCandidates.isEmpty()) {
			return;
		}
		// 省略部分代码……主要是排序
		
		// 接下来我们看Spring是如何扫包的,如何解析Configuration类的
		do {
			parser.parse(candidates);
			parser.validate();
			// 省略部分重织代码,即将candidates重置后重新织入,我们主要关注parse中扫包注入过程
		}
		while (!candidates.isEmpty());
		// 省略部分注入代码……
	}
	
——> public void parse(Set<BeanDefinitionHolder> configCandidates) {
		this.deferredImportSelectors = new LinkedList<>();
		for (BeanDefinitionHolder holder : configCandidates) {
			BeanDefinition bd = holder.getBeanDefinition();
			try {
				// MySpringConfig是注解式的所以走这里
				if (bd instanceof AnnotatedBeanDefinition) {
					parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
				}
				else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
					parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
				}
				else {
					parse(bd.getBeanClassName(), holder.getBeanName());
				}
			}
			// 省略部分catch代码……
		// 处理延迟导入的ImportSelectors
		processDeferredImportSelectors();
	}
	
——>	protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
		processConfigurationClass(new ConfigurationClass(metadata, beanName));
	}
	
——> protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
		// 执行@Condition选择性注入的条件
		if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
			return;
		}
		// 获取到@Configuration注解类,也就是MySpringConfig
		ConfigurationClass existingClass = this.configurationClasses.get(configClass);
		// 省略部分非必要性代码……
		// 递归处理配置类及其超类层次结构。实际上是在检测注解或是超类的一些格式/规范问题。
		SourceClass sourceClass = asSourceClass(configClass);
		do {
			sourceClass = doProcessConfigurationClass(configClass, sourceClass);
		}
		while (sourceClass != null);

		this.configurationClasses.put(configClass, configClass);
	}
	
	// Spring 扫描的核心
——> protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
			throws IOException {
		// 首先递归处理任何成员(嵌套)类
		processMemberClasses(configClass, sourceClass);

		// 解析@PropertySource注解,@PropertySource用来加载指定的属性文件。
		for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
			// 省略@PropertySource解析代码……
		}

		// 解析 @ComponentScan 注解
		Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
				sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
		if (!componentScans.isEmpty() &&
				!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
			for (AnnotationAttributes componentScan : componentScans) {
				// 通过初始化阶段的类路径扫描器扫描@ComponentScan标注范围内的所有类(ClassPathBeanDefinitionScanner)
				Set<BeanDefinitionHolder> scannedBeanDefinitions =
						this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
				// 检查扫描的定义集是否有其他配置类,并在需要时递归解析
				for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
					if (ConfigurationClassUtils.checkConfigurationClassCandidate(
							holder.getBeanDefinition(), this.metadataReaderFactory)) {
						parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName());
					}
				}
			}
		}
		// 处理所有的 @Import 注解,我们自定的BeanFactory后置处理器就是在这里被注册的!!
		processImports(configClass, sourceClass, getImports(sourceClass), true);

		// 处理所有@ImportResource 注解,@ImportResource主要用来装配XML配置文件
		AnnotationAttributes importResource =
				AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
		if (importResource != null) {
			String[] resources = importResource.getStringArray("locations");
			Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
			for (String resource : resources) {
				String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
				configClass.addImportedResource(resolvedResource, readerClass);
			}
		}

		// 处理单个 @Bean 注解方法
		Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
		for (MethodMetadata methodMetadata : beanMethods) {
			configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
		}

		// 处理接口的默认方法
		processInterfaces(configClass, sourceClass);

		// (如果有)处理超类
		if (sourceClass.getMetadata().hasSuperClass()) {
			String superclass = sourceClass.getMetadata().getSuperClassName();
			if (superclass != null && !superclass.startsWith("java") &&
					!this.knownSuperclasses.containsKey(superclass)) {
				this.knownSuperclasses.put(superclass, configClass);
				// 到超类,返回其注释元数据并递归
				return sourceClass.getSuperClass();
			}
		}

		// 没有超类->处理完成
		return null;
	}
	
	// @Import的解析是比较复杂的,Spring单独拿了出来
——> private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
			Collection<SourceClass> importCandidates, boolean checkForCircularImports) {
		// 省略非核心代码……
				for (SourceClass candidate : importCandidates) {
	// 候选类是ImportSelector实现类,走这里进行注册
	// 例如@EnableTransactionManagement注解,就是ImportSelector的实现
					if (candidate.isAssignable(ImportSelector.class)) {
						Class<?> candidateClass = candidate.loadClass();
						ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
						ParserStrategyUtils.invokeAwareMethods(
								selector, this.environment, this.resourceLoader, this.registry);
						if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
							this.deferredImportSelectors.add(
									new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
						}
						else {
							String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
							Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
							processImports(configClass, currentSourceClass, importSourceClasses, false);
						}
					}
	// 候选类是ImportBeanDefinitionRegistrar实现类,从这里进行注册
	// 例如,@EnableAspectJAutoProxy的关键类AspectJAutoProxyRegistrar就是这种实现,@EnableTransactionManagemen也有它的身影。
	// BeanFactory后置处理器,并非上诉两种实现类型
					else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
						Class<?> candidateClass = candidate.loadClass();
						ImportBeanDefinitionRegistrar registrar =
								BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
						ParserStrategyUtils.invokeAwareMethods(
								registrar, this.environment, this.resourceLoader, this.registry);
						configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
					}
	// BeanFactory直接实现BeanFactoryPostProcessor接口,既没有实现ImpostSelector也没有实现ImportBeanDefinitionRegistrar,则直接按照@Configuration方式解析
					else {
						this.importStack.registerImport(
								currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
		// BeanFactory后置处理器走processConfigurationClass递归完成解析工作
						processConfigurationClass(candidate.asConfigClass(configClass));
					}
				}
		// 省略异常处理代码……
	}

  到这里所有IOC的注册/扫描已经完成,也就是说这是容器中包括了项目中所需要的用到的大部分实例,当然@Lazy延迟加载的除外。
现在我们来总结一下注册过程:

  1. Spring扫描在第三阶段刷新上下文中invokeBeanFactoryPostProcessors完成,其会执行所有BeanDefinitionRegistryPostProcessor的实现,Spring默注册阶段默认会注入;ConfigurationClassPostProcessor;
  2. 扫描前,获取到由第二阶段注册中注入的启动配置文件(MySringConfig)并解析文件标注的注解;
  3. 首先,获取配置类的所有超类,若具有内部类,则需先递归解析;
  4. 第一步,解析所有@PropertySource注解,其作用是加载指定的属性文件
  5. 第二步,解析所有@ComponentScan注解3,通过初始化阶段的ClassPathBeanDefinitionScanner类路径扫描器完成递归扫描;
  6. 第三步,处理所有@Import注解,分为三种类型:
    • ImportSelector实现型,例如@EnableTransactionManagement注解,就是ImportSelector的实现;

    • ImportBeanDefinitionRegistrar手动注入型,例如,@EnableAspectJAutoProxy的关键类AspectJAutoProxyRegistrar就是这种实现,@EnableTransactionManagement中也有它的身影;

    • 其他类型Import,都按照@Configuration进行递归解析。 BeanFactory后置处理器既没有实现ImpostSelector也没有实现ImportBeanDefinitionRegistrar,则直接按照@Configuration方式解析。

  7. 第四步,处理所有@ImportResource注解,解析XML配置;
  8. 第五步,处理@Bean注解方法,注入Bean实例;
  9. 第六步,处理接口上的默认方法,注入默认实现方法;
  10. 最后,如果存在超类,则递归解析超类 ,否则结束扫描。
  结构图

Spring5.X源码分析(IOC/AOP)_第3张图片

执行BeanFactory后置处理器

  现在我们回到注册/扫描阶段我们忽略掉的那部分后置处理器执行代码。

  调用链
	// 以下代码来自,PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors
	
	// 省略注册/扫描阶段代码……
	
		// 现在,调用到目前为止已处理的所有处理器的postProcessBeanFactory回调。
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}
		else {
			// 调用向上下文实例注册的工厂处理器。
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}
		// 不要在这里初始化FactoryBeans:我们需要保留所有常规bean //未初始化,以使Bean工厂后处理器对其应用!!
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
		// 对BeanFactory后置处理器排序
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
				// 跳过-已在上述第一阶段处理过
			}
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}
		// 首先, 调用PriorityOrdered实现的BeanFactory后置处理器.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
		// 其次, 调用Ordered实现.
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
		// 最后, 调用其他BeanFactoryPostProcessors.
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
		// 清除缓存的合并bean定义,因为后处理器可能具有修改了原始元数据,例如替换值中的占位符...
		beanFactory.clearMetadataCache();
	}
	
	// 重点关注
——>	private static void invokeBeanFactoryPostProcessors(
			Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

		for (BeanFactoryPostProcessor postProcessor : postProcessors) {
			postProcessor.postProcessBeanFactory(beanFactory);
		}
	}

  BeanFactory后置处理器的执行和注册一样,也会分为三种优先级,PriorityOrdered—>Ordered—>其他BeanFactoryPostProcessors,演示中自定义的MyBeanFactoryPostProcessor 属于最后一级。
  执行时,直接从IOC中获取到通过Bean名称到对应的BeanFactoryPostProcessor对象,最后调用postProcessBeanFactory方法,postProcessBeanFactory就是我们MyBeanFactoryPostProcessor 中实现的BeanFactory后置增强方法。

  BeanFactory后置处理器总结

  Spring首先通过类路径加载器进行扫包同时完成BeanFactoryPost后置处理器的注册,注册完成后,根据指定的BeanName从容器中获取BeanFactoryPost后置处理器,并执行postProcessBeanFactory方法,实现增强。

  BeanFactory后置处理器在IOC初始化扫描后Bean实例构造方法执行前执行,可以实现对Bean实例的增强。但应用面比较鸡肋,而且在后续刷新上下文过程中Spring提供了更加强大的Bean前置增强处理器以及后置增强处理器。

  这也是AOP的实现的依仗,下面我们开始它的分析!

  结构图

Spring5.X源码分析(IOC/AOP)_第4张图片

刷新上下文阶段 - 注册Bean增强处理器

  Spring为Bean实例提供了两种Bean增强处理器,前置/后置处理器。也正是因为IOC提供的增强处理器,使得AOP可以在类初始化之前织入代码实现增强,这个过程是通过动态代理实现的。

  想要在后续使用增强处理器,首先将其注入到容器中,下面我们来看一下它的调用链。

  非常建议开启AOP注解@EnableAspectJAutoProxy(MySpringConfig上标注),这样可以更加直观的进行调试。

  调用链
	// 调用过程从AbstractApplicationContext.refresh()开始registerBeanPostProcessors(beanFactory);

——>	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}
	// 在之前阶段IOC已经做了非常多的工作,使得后续注入工作变得非常简单
——>	public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// 与之前注入一样,
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// 排序 PriorityOrdered —> Ordered —> 其他.
		// 省略部分代码……

		// 首先, 注册PriorityOrdered实现的BeanPostProcessors.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// 其次, 注册Ordered实现的BeanPostProcessors.
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// 然后,注册其他的BeanPostProcessors
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// 最后, 重新注册所有内部BeanPostProcessor.
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// 重新注册用于将内部bean检测为ApplicationListener的后处理器,将其移至处理器链的末尾(用于拾取代理等).
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}
	
——>	private static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

		for (BeanPostProcessor postProcessor : postProcessors) {
			beanFactory.addBeanPostProcessor(postProcessor);
		}
	}
	
——>	public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
		// 省略日志部分代码……
		this.beanPostProcessors.add(beanPostProcessor);
	}
——>	private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
注册Bean增强处理器总结

  实现一个增强处理器,只需要实现BeanPostProcessor接口。Spring对于这类增强处理器,使用CopyOnWriteArrayList进行存储,间接的说明了这类数据是读多写少的。

  结构图:

Spring5.X源码分析(IOC/AOP)_第5张图片

刷新上下文阶段 - 实例化所有剩余的单例Bean

  这一阶段需要将之前阶段注入的Bean进行实例化(调用构造),除此之外在实例化过程中实现增强。

  调用链
// 调用过程从AbstractApplicationContext.refresh()开始finishBeanFactoryInitialization(beanFactory);

——>	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// 省略部分组件初始化代码……
		// 实例化所有剩余的(非延迟初始化)单例
		beanFactory.preInstantiateSingletons();
	}

	// 查看preInstantiateSingletons的默认实现DefaultListableBeanFactory
——>	public void preInstantiateSingletons() throws BeansException {
		// 省略获取所有实例代码……
		// 非惰性单例bean的初始化...
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						final FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
											((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else {
					getBean(beanName);
				}
			}
		}
		// 触发所有适用bean的初始化后回调...
		// 忽略部分代码……
	}
	
	// 我们只看关键代码,Bean如何实例化的?
——>	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}
	
	// doGetBean代码比较长,主要区别是否有构造方法,有参/无参构造、单例/原型等,最终调用createBean进行创建,这里就不贴代码了。
	//IDEA Ctrl+Alt+B 查看createBean的默认实现AbstractAutowireCapableBeanFactory
——>		protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
		// createBean中主要是为后阶段反射以及后置增强做准备工作。
		// 部分准备代码……
		try {
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		// 忽略catch……
	}

——>	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
		// 忽略部分代码……
		
		// 允许后处理器修改合并的bean定义。
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

		// 主要解决生成Bean实例的循环依赖问题
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// 初始化bean实例.
		Object exposedObject = bean;
		try {
			populateBean(beanName, mbd, instanceWrapper);
			// 初始化给定的bean实例,应用工厂回调以及init方法和bean后处理器
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		// 省略部分代码……
		return exposedObject;
	}

——>	protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
	// 调用实现Aware接口方法,只针对三种Aware接口BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			// Bean前置增强处理器
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			// 反射生成Bean实例
			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()) {
		// Bean前置增强处理器
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
		return wrappedBean;
	}

——> public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {
		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessBeforeInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}
——> public List<BeanPostProcessor> getBeanPostProcessors() {
		return this.beanPostProcessors;
	}

  还记得Spring注入Bean增强处理器时存放的CopyOnWriteArrayList名称吗?是不是也是beanPostProcessors?所以,我们来总结一下。

实例化所有剩余的Bean总结

  通过以上分析,我们可以知道,加载的过程大概是这样的:

  1. Spring IOC在扫描时将所有Bean实例注入到了容器,此时容器中的实例只是一个BeanName与实例Class对象的映射;
  2. 然后,又将Bean增强处理器装配到了容器中;
  3. 随后,循环实例化所有Bean,并在实例化过程中获取所有Bean前置增强处理器,执行前置增强;
  4. 之后,通过反射技术实例化Bean;
  5. 最后,实例化结束,执行所有Bean后置增强处理器,并刷新容器实例。
  结构图

Spring5.X源码分析(IOC/AOP)_第6张图片

AOP源码分析

  从上诉分析中我们了解到,Spring IOC采用一个ConcurrentHashMap来存储BeanDefinition(Bean实例)。

  同时,为所有的Bean提供了Bean的前置/后置增强处理器,而且只需要实现BeanPostProcessor接口IOC就会在启动时我们执行对应的增强方法。

  上面这两点恰恰就是AOP的关键,接下来我们就看看AOP在Bean的增强处理器中做了什么事。

环境搭建

	// 1、MySpringConfig加上@EnableAspectJAutoProxy标注
@Aspect
@Component
public class LoginAop {
    /**
     * @Pointcut 定义切入点
     *
     * @Pointcut(value = "execution (* com.lming.service.*..*.*(..))")  service.所有子包 下面所有的类所有的方案
     */
    @Pointcut("execution (* com.lming.service..*.*(..))")
    public void loginAop() {
    }

    /**
     * 前置通知
     *
     * @param joinPoint
     */
    @Before("loginAop()")
    public void doBefore(JoinPoint joinPoint) {
        System.out.println(">>>>>>>前置通知<<<<<<<<<<< ");
    }

    /**
     * 后置通知
     */
    @After("loginAop()")
    public void doAfter(JoinPoint joinPoint) {
        System.out.println(">>>>>>>>后置通知<<<<<<<<<");
    }

    /**
     * 环绕通知
     *
     * @param joinPoint
     */
    @Around("loginAop()")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println(">>>>环绕通知之前执行...>>>>>>");
        joinPoint.proceed();// 执行目标方案
        System.out.println(">>>>环绕通知之后执行...>>>>>>");
    }

    /**
     * 运行通知
     */
    @AfterReturning("loginAop()")
    public void afterReturning(JoinPoint joinPoint) {
        System.out.println("运行通知执行.....");
    }

    /**
     * 异常通知
     *
     * @param joinPoint
     */
    @AfterThrowing("loginAop()")
    public void afterThrowing(JoinPoint joinPoint) {
        System.out.println(">>>>>异常通知");
    }
}

@Component
public class MemberServiceImpl   implements  InitializingBean, MemberService {
    public MemberServiceImpl() {
        System.out.println("执行无参构造函数....");
    }

    public String login(String userName, String passWord) {
        int i = 1 / 0;
        System.out.println(">>>>正在执行登陆业务逻辑>>>>> userName:" + userName + "passWord:" + passWord);
        return ">>>>登陆业务逻辑..<<<<";
    }

    public void afterPropertiesSet() throws Exception {
        System.out.println("执行自定义bean的init方法");
    }
}

public interface MemberService {
    public String login(String userName, String passWord);
}

AOP源码分析

  分析一个框架的源码,首先需要知道它解决了什么问题、怎么使用的、了解他的大致原理,这在我们分析源码时是不可或缺的知识。

  随后,分析源码首先需要有一个目的,然后找到入口,步步深入,并记录整个过程,这也是非常重要的,特别想面对Spring这种代码非常紧密的框架时,书签笔迹可以帮你快速定位代码。

  目的: AOP在Bean的增强处理器中做了什么事?如何实现的切面编程?
  入口: @EnableAspectJAutoProxy

  调用链
	@Import(AspectJAutoProxyRegistrar.class)

	// ImportBeanDefinitionRegistrar 手动注入
——> class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

		AnnotationAttributes enableAspectJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
		if (enableAspectJAutoProxy != null) {
			if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
				// 将创建好的AOP代理注入到IOC,BeanName = internalAutoProxyCreator
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
			if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
				AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
			}
		}
	}
}

——>	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
		return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
	}
	
	// 注入了AnnotationAwareAspectJAutoProxyCreator
——>	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
			BeanDefinitionRegistry registry, @Nullable Object source) {
		return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
	}

  @EnableAspectJAutoProxy注解最终注入了AnnotationAwareAspectJAutoProxyCreator类。

  这时候线索中断了,接下来应该调用哪个方法呢?

  我们查看一下AnnotationAwareAspectJAutoProxyCreator类图:
Spring5.X源码分析(IOC/AOP)_第7张图片
  我们可以发现在AnnotationAwareAspectJAutoProxyCreator的类图中实现了BeanPostProcessor、ProxyConfig4、BeanFactoryAware5 等几个超类。

  在IOC中我们叙述过,实现BeanPostProcessor可以对Bean进行增强。IOC在第三阶段刷新上下文时会调用所有BeanPostProcessor实现的前置增强postProcessBeforeInitialization以及后置增强方法postProcessAfterInitialization

  也就是说,AOP这时候注入的AnnotationAwareAspectJAutoProxyCreator类中(间接)实现了这两个方法,并且在IOC刷新上下文时会被调用,所以找到它们就可以继续分析。

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) {
		return bean;
	}
	// 如果Bean被子类标识为要代理的Bean,则使用配置的拦截器创建代理。
	@Override
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

  最终,我们在AbstractAutoProxyCreator中找到了他们,AOP在其前置增强中并未做任何操作,所以我们关注后置增强,通过标注我们可以发现它是在创建一个代理。

  我们知道代理分为两种,动态代理和静态代理6,这里的程序必然是使用动态代理,那么动态代理又分为两种方式创建JDK、CGlib动态代理,AOP是采用的何种方式进行创建的呢?

继续调用链:

	protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// 如果有建议,请创建代理。
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

——> protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
			@Nullable Object[] specificInterceptors, TargetSource targetSource) {
	// 依靠是否具有实现类(setProxyTargetClass),判断使用JDK还是CGlib动态代理
		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());
	}
	
——> public Object getProxy(@Nullable ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
	}

  我们首先观察AOP是如何选用何种方式创建代理类的,再来看具体的创建过程。

	protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		return getAopProxyFactory().createAopProxy(this);
	}

	// 查看createAopProxy(this)的默认实现DefaultAopProxyFactory
——>	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
			Class<?> targetClass = config.getTargetClass();
			if (targetClass == null) {
				throw new AopConfigException("TargetSource cannot determine target class: " +
						"Either an interface or a target is required for proxy creation.");
			}
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}

  所以我们可以得知,Spring AOP依据getTargetClass选择何种动态代理来创建实例,也就是说Spring AOP根据当前类是否是一个实现类来选择具体的动态代理创建方式。

  若当前Bean实例是接口的实现类,则使用JDK动态代理创建;

  若当前Bean实例没有实现任何接口,则使用CGlib动态代理创建。

  回到,getProxy,继续观察getProxy(classLoader)是如何创建动态代理的,查看getProxy的JdkDynamicAopProxy实现,发现JdkDynamicAopProxy实现了InvocationHandler接口。

  这时候我们就明白了,通过JDK创建动态代理必须实现InvocationHandler接口,实现invoke方法,通过Proxy.newProxyInstance()即可动态的创建一个代理类。

	public Object getProxy(@Nullable ClassLoader classLoader) {
		if (logger.isTraceEnabled()) {
			logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
		}
		Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
		findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}

   CglibAopProxy的getProxy()实现调用了getCallbacks(),getCallbacks()根据ProxyConfig4中targetSource判断使用什么方式创建代理类。

  Cglib方式默认提供两种静态内部内实现,StaticUnadvisedExposedInterceptor(单例)、DynamicUnadvisedExposedInterceptor(原型),根据targetSource判断Bean实例是单例还是原型,选择不同的方式管理代理类7

  

  最后,我们获取到了代理类对象的话,就可以在invoke方法中,拦截切面配置的需要织入的方法,对其进行前置/后置/异常/环绕/事务等增强操作。

  但是,这些增强并不是无需执行的,那么Spring怎么保证这些增强执行顺序的呢?Spring通过递归实现了一个调用链,通过控制递归的条件可以保证不同类型增强代码的链型执行顺序。

AOP源码总结

  Spring AOP通过IOC提供实现BeanPostProcessor接口的来执行后置增强方法,在后置增强方法中对实例Bean创建代理对象,并根据实例是否为接口实现类来判断采用JDK还是CGlib动态代理。

  当被代理的对象的方法执行时,判断是否属于需要织入切面的方法,切面配置由IOC刷新上下文是注入容器。

  AOP是支持多种增强的(前置、后置、异常、环绕等),而其执行的顺序则是通过递归实现的调用链设计模式,保证不同增强代码的链型执行顺序。

  1. 第一步,通过@import手动注入AspectJAutoProxyRegistrar.class(ImportBeanDefinitionRegistrar的实现)到IOC容器中;
  2. 第二步spectJAutoProxyRegistrar.class最终会手动注入BeanPostProcessor接口的实现类实例;
  3. 第三步,IOC启动第三阶段刷新上下文,完成所有扫包到的Bean实例注入时,会对所有Bean实例执行所有的BeanPostProcessor(BeanPostProcessor的实现会先于Bean实例注入到IOC容器);
  4. 第四步,BeanPostProcessor主要功能是可以实现对Bean实例的增强,AOP在增强过程中根据Bean实例是否为接口实现类判断使用何种动态代理对Bean进行代理;
  5. 第五步,AOP通过BeanFactoryAware可以获取到IOC容器中扫包过程中注入进去的AOP配置信息,最终被代理的Bean实例的方法(通常是service业务包下面的方法)开始执行;
  6. 第六步方法被代理后并不会直接执行,而是交由**jdk的invoke()cglib的intercept()**代理执行,最终AOP通过代理规则判断当前执行的方法是否需要执行增强代码了(增强代码则是通过反射执行的)。
  7. 最后,AOP通过递归实现切面方法执行逻辑的调用链,保证不同增强代码的链型执行顺序。

总结

  本文重点考量IOC、AOP的源码实现以及它们之间的内在联系,忽略了其他的散项代码。Spring中还包含了非常多的设计模式以及优秀的设计理念,这是值得我们仔细考量的,比如AOP中的调用链模式、Bean实例的循环依赖问题等等。

  有兴趣的同学就去干它吧!

  好啦!本文到这里就结束啦,篇幅比较长,耐心阅读,相信你会有所得~

  差点忘了,最后的分析图,赶紧贴上。

Spring5.X IOC与AOP源码分析图:

Spring5.X源码分析(IOC/AOP)_第8张图片
最后,附上一张分析书签。
Spring5.X源码分析(IOC/AOP)_第9张图片


  1. 表示针对每次请求都会产生一个新的Bean对象,并且该Bean对象仅在当前Http请求内有效。 ↩︎

  2. 作用域表示煤气请求都会产生一个新的Bean对象,并且该Bean仅在当前Http session内有效。 ↩︎

  3. @ComponentScan中的includeFilters、excludeFilters都将在此时被解析。 ↩︎

  4. ProxyConfigAOP创建代理的配置API。 ↩︎ ↩︎

  5. BeanFactoryAware实现了BeanFactoryAware接口的bean,可以直接通过beanfactory来访问spring的容器。 ↩︎

  6. 静态代理需要生成代理类,动态代理可以通过字节码技术动态构建。 ↩︎

  7. 对应到实例中就是LoginAop。 ↩︎

你可能感兴趣的:(实践总结)