Spring源码学习(二) | 主流程分析

前言

       上一篇介绍了源码结构以及Spring容器内部成员,本文着重分析学习spring容器启动的主流程过程:如下代码的整个流程,以及在这个过程中可以运用在实际工作中的知识点。(文中涉及到的概念如BeanDefinition,BeanDefinitionHolder等等如不清楚请移步上文末尾翻阅)

  • AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
  • context.register(AppConfig.class);
  • context.refresh();

主流程分析一:new AnnotationConfigApplicationContext()

       实例化上下文,准备AnnotatedBeanDefinitionReaderClassPathBeanDefinitionScanner,简称reader和scanner。
reader:是一个BeanDefinition读取器,给一个类给他,他帮你转换成为BeanDefinition。在此期间,Spring把一些bean变成了BeanDefinition,比如ConfigurationClassPostProcessor等等6个类,用于后续流程使用。
scanner:能够扫描一个类、包,并且转换成BeanDefinition。源码这里是没有使用这个对象,源码使用的是spring自己new的一个ClassPathBeanDefinitionScanner。这个对象用于程序员手动调用scan方法进行扫描包。这里不过多阐述。

	public AnnotationConfigApplicationContext() {
		StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
		this.reader = new AnnotatedBeanDefinitionReader(this);
		createAnnotatedBeanDefReader.end();
		// scanner用来扫描包或者类,继而转换成bd
		// 实际上扫描包不是scanner这个对象
		// 是spring自己new的一个ClassPathBeanDefinitionScanner
		// 这里的scanner是提供给程序员手动调用scan方法的一个类AnnotationConfigApplicationContext.scan
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

下面看一下AnnotatedBeanDefinitionReader干了些什么:
着重看一下AnnotationConfigUtils.registerAnnotationConfigProcessors(this.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);
	}
	public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {

		// 通过registry环境获取beanfactory空的工厂
		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		// 给工厂添加一些原料
		if (beanFactory != null) {
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				// AnnotationAwareOrderComparator主要能解析@order注解和@priority (排序)
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				// ContextAnnotationAutowireCandidateResolver提供处理延迟加载的功能
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}

		// BeanDefinitionHolder包含beanDefinition和beanname,主要用于方便封装参数
		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

		// beanDefinition的注册,注册ConfigurationClassPostProcessor
		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			// 这里ConfigurationClassPostProcessor的类型是BeanDefinitionRegistryPostProcessor
			// BeanDefinitionRegistryPostProcessor实现BeanFactoryPostProcessor接口
			// 把一个普通类实例化一个BeanDefinition
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			// BeanDefinition放进beanDefinitionMap以及BeanDefinitionHolder(BeanDefinitionRegistry的registerBeanDefinition方法)
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// beanDefinition的注册,注册AutowiredAnnotationBeanPostProcessor
		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));
		}

		// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
		// beanDefinition的注册,支持JSR-250,则注册CommonAnnotationBeanPostProcessor
		if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
		// beanDefinition的注册,支持JPA,则注册PersistenceAnnotationBeanPostProcessor
		if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition();
			try {
				def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
						AnnotationConfigUtils.class.getClassLoader()));
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
			}
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// beanDefinition的注册,注册EventListenerMethodProcessor
		if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
		}

		// beanDefinition的注册,注册DefaultEventListenerFactory
		if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
		}

		return beanDefs;
	}

由代码和注释可知道,Spring的reader流程如下

  • 1.从容器中取一个beanFactory工厂,如果beanFactory不为空则为工厂添加一些原料,如AnnotationAwareOrderComparator:提供排序的一些功能。ContextAnnotationAutowireCandidateResolver:提供处理延迟加载的功能
  • 2.实例化一个元素为BeanDefinitionHolder的set集合,BeanDefinitionHolder包含beanDefinition和beanname,主要用于方便封装参数
  • 3.注册6个类为beanDefinition,并将它们添加至第二步的set集合以及beanDefinitionMap中,用于后续使用。(ConfigurationClassPostProcessor类后面重点关注)
    其中分别为:ConfigurationClassPostProcessor,AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,PersistenceAnnotationBeanPostProcessor,EventListenerMethodProcessor,DefaultEventListenerFactory。

我们看一下源码中Spring是如何把一个类变为BeanDefinition的,以及如何放入beanDefinitionMap和BeanDefinitionHolder:

RootBeanDefinition 是BeanDefinition接口的一个实现,我们只需要把要转换的类的class放入构造器即可,下面例子是ConfigurationClassPostProcessor类。
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);

	// beanDefinition的注册,注册ConfigurationClassPostProcessor
	if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		// 把一个普通类实例化一个BeanDefinition
		RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
		def.setSource(source);
		// BeanDefinition放进beanDefinitionMap以及BeanDefinitionHolder(BeanDefinitionRegistry的registerBeanDefinition方法)
		beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
	}

	private static BeanDefinitionHolder registerPostProcessor(
			BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {

		definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		// 核心
		registry.registerBeanDefinition(beanName, definition);
		return new BeanDefinitionHolder(definition, beanName);
	}

核心在于registry.registerBeanDefinition(beanName, definition);接口有3个实现,最终关键代码都是:
this.beanDefinitionMap.put(beanName, beanDefinition);放入beanDefinitionMap
在这里插入图片描述
在这里插入图片描述
放入beanDefinitionMap之后,就是实例化BeanDefinitionHolder,并把它装入第二步流程中的set集合

主流程分析二:context.register(AppConfig.class);

AppConfig类:

@Configuration
@ComponentScan("com.demo")
public class AppConfig {
}

context.register:把AppConfig类注册为一个BeanDefinition,然后放到DefaultListableBeanFactory的beanDefinitionMap里面

	@Override
	public void register(Class<?>... componentClasses) {
		Assert.notEmpty(componentClasses, "At least one component class must be specified");
		StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register")
				.tag("classes", () -> Arrays.toString(componentClasses));
		//核心
		this.reader.register(componentClasses);
		registerComponentClass.end();
	}

	public void register(Class<?>... componentClasses) {
		for (Class<?> componentClass : componentClasses) {
		    //核心
			registerBean(componentClass);
		}
	}

	public void registerBean(Class<?> beanClass) {
		doRegisterBean(beanClass, null, null, null, null);
	}

核心方法doRegisterBean:

1.解析传入的类class,用这个class实例化AnnotatedGenericBeanDefinition 对象,这个类是BeanDefinition接口的第二个实现
2.BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
调用registry的registerBeanDefinition,把实例化的AnnotatedGenericBeanDefinition 放入beanDefinitionMap和BeanDefinitionHolder

	private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
			@Nullable BeanDefinitionCustomizer[] customizers) {

		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
			return;
		}

		abd.setInstanceSupplier(supplier);
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
		abd.setScope(scopeMetadata.getScopeName());
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
		if (qualifiers != null) {
			for (Class<? extends Annotation> qualifier : qualifiers) {
				if (Primary.class == qualifier) {
					abd.setPrimary(true);
				}
				else if (Lazy.class == qualifier) {
					abd.setLazyInit(true);
				}
				else {
					abd.addQualifier(new AutowireCandidateQualifier(qualifier));
				}
			}
		}
		if (customizers != null) {
			for (BeanDefinitionCustomizer customizer : customizers) {
				customizer.customize(abd);
			}
		}

		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
		
		// 调用registry的registerBeanDefinition,把beanDefinition放入beanDefinitionMap
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}

主流程分析三:context.refresh();

context.refresh():准备好bean工厂,实例化对象

	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

			// 准备工作包括设置启动时间,是否激活标识位
			// 初始化属性源(property,source)配置
			prepareRefresh();

			// 返回一个beanFactory,因为即将对工厂进行初始化
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 准备工厂
			prepareBeanFactory(beanFactory);

			try {
				// 无任何处理
				postProcessBeanFactory(beanFactory);

				StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
				
				// 执行一些已经注册过的BeanFactoryPostProcessor方法
				// 设置执行自定义的BeanFactoryPostProcessor
				invokeBeanFactoryPostProcessors(beanFactory);

				// 注册BeanPostProcessors
				registerBeanPostProcessors(beanFactory);
				
				beanPostProcess.end();
				initMessageSource();
				initApplicationEventMulticaster();
				onRefresh();
				
                // 注册监听器
				registerListeners();
               
                //完成工厂初始化
				finishBeanFactoryInitialization(beanFactory);
				finishRefresh();
			}
			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}
				destroyBeans();
				cancelRefresh(ex);
				throw ex;
			}
			finally {
				resetCommonCaches();
				contextRefresh.end();
			}
		}
	}

这里我们着重关注prepareBeanFactory准备工厂和invokeBeanFactoryPostProcessors执行一些已经注册过的BeanFactoryPostProcessor方法(即:reader里面注册过的ConfigurationClassPostProcessor等等)

prepareBeanFactory准备工厂:配置一些标准的特征,比如上下文加载器以及回调的后置处理器

  • 1、添加一个类加载器
  • 2、添加bean表达式解释器,为了能够让我们的beanFactory去解析bean表达式,比如jsp页面el表达式
  • 3、添加一个后置处理器ApplicationContextAwareProcessor
  • 4、添加了自动注入别忽略的列表
  • 5、对象的依赖替换
  • 6、添加了一个ApplicationListenerDetector后置处理器
  • 7、加载一些默认环境和系统配置
	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// Tell the internal bean factory to use the context's class loader etc.
		// 1.添加一个类加载器
		beanFactory.setBeanClassLoader(getClassLoader());
		if (!shouldIgnoreSpel) {
			// 2.添加bean表达式解释器,为了能够让我们的beanFactory去解析bean表达式   比如el表达式获取bean里面的属性在页面
			beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		}
		// 对象与字符串的转换
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		// 3.添加一个后置处理器ApplicationContextAwareProcessor,能在bean中获取各种*aware。
		// 会在bean的实例化过程中依次执行list里面的各种后置处理器Processor
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		// 4.添加了一些自动注入被忽略的列表
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationStartup.class);

		// BeanFactory interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		// 对象的依赖替换,比如依赖BeanFactory这么一个类,就用beanFactory替换它
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// Register early post-processor for detecting inner beans as ApplicationListeners.
		// 5.添加一个后置处理器ApplicationListenerDetector(基本不怎么用)
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		// 加载一些时间相关
		if (!IN_NATIVE_IMAGE && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// Register default environment beans.
		// 加载一些默认的环境配置。系统配置和系统环境配置
		// systemProperties  systemEnvironment
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
		if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
			beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
		}
	}

invokeBeanFactoryPostProcessors:执行一些已经注册过的(ConfigurationClassPostProcessor)和自定义的BeanFactoryPostProcessor

首先学习一个知识点:BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor
BeanDefinitionRegistryPostProcessor继承BeanFactoryPostProcessor,拓展了一个postProcessBeanDefinitionRegistry方法。

reader流程中添加的6个类:
ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor接口
其他5个是实现BeanFactoryPostProcessor接口

在这里插入图片描述
1.此方法传了2个参数,分别是工厂beanFactory,以及程序员手动添加的beanFactoryPostProcessors
2.定义了3个list:

  • 存放BeanFactoryPostProcessor:List<<>BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
  • 存放BeanDefinitionRegistryPostProcessor:List<<>BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
  • 存放程序员自定义和spring内部自己的BeanDefinitionRegistryPostProcessor汇总的list:List<<>BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

流程:

  • 1.拆分程序员自定义的BeanFactoryPostProcessor分别放入BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor的相关list,并且如果是BeanDefinitionRegistryPostProcessor,则执行拓展方法postProcessBeanDefinitionRegistry(程序员手动添加的)
  • 2.通过getBeanNamesForType方法从工厂beanFactory获取BeanDefinitionRegistryPostProcessor类型的bean名字,并通过名字获取bean,放入存放BeanDefinitionRegistryPostProcessor的list
  • 3.排序spring内部的BeanDefinitionRegistryPostProcessor类型的list
  • 4.汇总spring内部和程序员自定义的BeanDefinitionRegistryPostProcessor类型的集合
  • 5.执行spring内部的BeanDefinitionRegistryPostProcessor中拓展postProcessBeanDefinitionRegistry方法(spring内部的)
	public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		Set<String> processedBeans = new HashSet<>();

		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			// 自定义的BeanFactoryPostProcessors.
			// 拆分为存放BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor的2个list,
			// spring为什么要拆分?因为BeanDefinitionRegistryPostProcessor实现了BeanFactoryPostProcessor接口,前者有拓展的功能,分开处理
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}

			// 放的spring内部实现的BeanFactoryPostProcessor
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			// 通过type类型获取bean的名字,type指的BeanDefinition中描述当前类的class类型
			// ConfigurationClassPostProcessor就是属性BeanDefinitionRegistryPostProcessor这个类型
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			// 这里获取了n个在之前reader的时候配置的spring内部的BeanFactoryPostProcessor后置处理器,用于现在插手spring实例化bean的过程
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			// 排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			// 合并自定义和spring内部的list
			registryProcessors.addAll(currentRegistryProcessors);
			/**
			 * BeanFactoryPostProcessors方法调用****执行postProcessBeanDefinitionRegistry拓展方法
			 * 注意是拓展方法
			 */
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
			currentRegistryProcessors.clear();
            ......
            ......
            }
     }

下面看一看程序员如何手动传入BeanFactoryPostProcessor呢???

只需要调用上下文的addBeanFactoryPostProcessor方法,传入自己构造的BeanFactoryPostProcessor就行了
context.addBeanFactoryPostProcessor(new MyBeanFactoryProcessor());
在这里插入图片描述

在这里插入图片描述
那么在这里,小伙伴有没有发现一个很牛逼的一点:我们居然已经可以插手spring容器的启动过程了???因为这里自定义一个MyBeanFactoryProcessor,我们把容器的userDaoImpl bean改为了原型prototype,每次获取的都是不同的bean

      由此,本文的学习就这里,下文将着重分析学习ConfigurationClassPostProcessor类的作用。


      上一篇:Spring源码学习(一) | 源码结构以及Spring容器内部成员概述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
【资源说明】 1、该资源包括项目的全部源码,下载可以直接使用! 2、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习借鉴。 3、本资源作为“参考资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研,自行调试。 基于SpringMVC+Spring+MyBatis (SSM) 架构的高效率便捷开发框架源码+项目说明.zip 本项目是一个整合 **SpringMVC+Spring+MyBatis(SSM)** 框架的 **Demo**。<br> 拥有高效率便捷开发模式,使开发人员更专注于业务,达到面向业务开发。<br> 项目使用 **Maven** 构建,便于项目管理,支持 **Oracle、MySql** 等主流数据库。<br> 前端展示界面采用基于 **Boostrap** 实现的响应式布局,并集成了一系列的动画效果插件,整体界面简洁、美观大方并可优雅的与后台完成交互操作。<br> 项目封装了一系列常用方法、部署运行简单,便于个人或企业进行高效开发。 ## 一、项目开发环境&工具(Environment&Tools) * MacOS Sierra / Windows 7 * MySql 5.7 * JDK 1.8 * CentOS 7 * IntelliJ IDEA 2017.2.5 / Eclipse 4.6.1 * Navicat Premium 11.1.12 * Maven 3.3.9 * Jetty 9.4.6.v20170531 / Tomcat 9.0.1 ## 、技术选型(Technology) #### 1.服务端技术(Server) 名称 | 版本号 | 网址 --- | --- | --- Spring Framework | 4.3.13.RELEASE | [http://projects.spring.io/spring-framework/](http://projects.spring.io/spring-framework/) Shiro | 1.4.0 | [http://shiro.apache.org](http://shiro.apache.org) AspectJ | 1.8.13 | [http://www.eclipse.org/aspectj/](http://www.eclipse.org/aspectj/) MyBatis | 3.4.5 | [http://www.mybatis.org/mybatis-3/zh/index.html](http://www.mybatis.org/mybatis-3/zh/index.html) MyBatis Generator | 1.3.6 | [http://www.mybatis.org/generator/index.html](http://www.mybatis.org/generator/index.html) PageHelper | 5.1.2 | [http://git.oschina.net/free/Mybatis_PageHelper](http://git.oschina.net/free/Mybatis_PageHelper) Druid | 1.1.6 | [https://github.com/alibaba/druid](https://github.com/alibaba/druid) Jackson | 2.9.3 | [https://github.com/FasterXML/jackson](https://github.com/FasterXML/jackson) Dom4j | 1.6.1 | [http://www.dom4j.org](http://www.dom4j.org) Ehcache | 2.6.11| [http://www.ehcache.org/](http://www.ehcache.org/) Logback | 1.2.3 | [https://logback.qos.ch](https://logback.qos.ch) Maven | 3.3.9 | [http://maven.apache.org/](http://maven.apache.org/) #### 2.前端技术(Web) 名称 | 版本号 | 网址 --- | --- | --- angular | - | [https://angularjs.org](https://angularjs.org) awesome-bootstrap-checkbox | - | [https://github.com/flatlogic/aw

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值