Запуск контейнера серии исходного кода Spring

Spring

Процесс весенней загрузки


目录

1. Создание демо

  • DemoКод очень простой, вся структура проекта выглядит следующим образом:
    Demo工程结构图
  • pomполагаться
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.8.RELEASE</version>
</dependency>
  • Два занятия в рамках пакета услугOrderService,UserServiceтолько что добавлен@ServiceАннотация, два класса в пакете daoOrderDao,UserDaoтолько что добавлен@Repositoryаннотация.MainApplicationписать только в классеmain()метод. код показывает, как показано ниже:
public static void main(String[] args) {
	AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

    UserService userService = applicationContext.getBean(UserService.class);
    System.out.println(userService);

    OrderService orderService = applicationContext.getBean(OrderService.class);
    System.out.println(orderService);

    UserDao userDao = applicationContext.getBean(UserDao.class);
    System.out.println(userDao);

    OrderDao orderDao = applicationContext.getBean(OrderDao.class);
    System.out.println(orderDao);

    applicationContext.close();
}
  • AppConfigКласс является классом конфигурации, и к классу добавляются две аннотации.@ConfigurationпоказыватьAppConfigэто класс конфигурации, плюс@ComponentScanсказатьSpringКакие пакеты сканировать, код такой:
@Configuration
@ComponentScan("com.tiantang.study")
public class AppConfig {
}

2. Старт

  • бегатьMainApplicationсерединаmain()метод, такойSpringКонтейнер работает. Консоль выводитUserService,OrderService,UserDao,OrderDaoизhashкод.
  • Затем приходит проблема, по сравнению с прошлымxmlСпособ настройки, теперь всего несколько строк простого кода,SpringКонтейнер может работать, и мы можем получить его из контейнера.Bean,SpringКак это делается внутри? Ниже приведен пошаговый анализSpringЗапустите исходный код.

3. Вход

  • Вход в программу естьmain()метод, из кода видно, что основной код состоит только из одной строки,new AnnotationConfigApplicationContext(AppConfig.class), с этой строкой кода,SpringКонтейнер создан, и тогда мы можем пройтиgetBean()Получить объект из контейнера. Поэтому, анализируяSpringисходный код, изAnnotationConfigApplicationContextПараметризованный конструктор начинается с .
  • AnnotationConfigApplicationContextа такжеClassPathXmlApplicationContextЭффект тот же, первый соответствует использованиюJavaConfigприменение технологии, последняя соответствуетXMLНастроенное приложение

4. Основные понятия

  • в ходе выполненияSpringПрежде чем читать исходный код, вам необходимо понять несколько концепций.
    1. Springпередаст всеSpringУправляемые классы, сканируйте ихclassфайл, разобрать его наBeanDefinition,существуетBeanDefinitionбудет описывать информацию о классе, например: является ли этот класс синглтоном,BeanТип, будь то ленивая загрузка, от каких классов зависит и модель с автоматическим подключением.SpringКогда объект создается, он основывается наBeanDefinitionинформация для созданияBean.
    1. SpringКонтейнеры можно понимать в этой статье просто какDefaultListableBeanFactory,этоBeanFactoryКласс реализации этого класса имеет несколько очень важных свойств:beanDefinitionMapЯвляетсяmap, хранитьbeanсоответствующийBeanDefinition;beanDefinitionNamesЯвляетсяListколлекция для хранения всехbeanизname;singletonObjectsЯвляетсяMap, используется для хранения всех созданных синглетоновBean.
    1. SpringПостпроцессоров много, но в итоге их можно разделить на два, одинBeanFactoryPostProcessor, одинBeanPostProcessor. Цель первого - вмешатьсяBeanFactoryпроцесс создания, последний используется для вмешательстваBeanпроцесс создания. Роль постпроцессора очень важна.beanсоздание иAOPРеализация все зависит от постпроцессора.

5. Конструктор AnnotationConfigApplicationContext

  • AnnotationConfigApplicationContextПараметр конструктора представляет собой массив переменных, вы можете передать несколько классов конфигурации, в это времяDemo, только передаетсяAppConfigкласс.
  • В конструкторе первый вызовthis(),существуетthis()Инициализируется вызовом конструктора родительского классаBeanFactory, а в контейнере зарегистрировано 7 постпроцессоров. тогда позвониregister(), поместите параметры конструктора вBeanDefinitionMapсередина. окончательное исполнениеrefresh()метод, который представляет собой всюSpringЯдро запуска контейнера, эта статья также будет посвящена анализуrefresh()Течение и функция метода.
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
	// 会初始化一个BeanFactory,为默认的DefaultListableBeanFactory
	// 会初始化一个beanDefinition的读取器,同时向容器中注册了7个spring的后置处理器(包括BeanPostProcessor和BeanFactoryPostProcessor)
	// 会初始化一个扫描器,后面似乎并没有用到这个扫描器,在refresh()中使用的是重新new的一个扫描器。
	this();
	// 将配置类注册进BeanDefinitionMap中
	register(annotatedClasses);
	refresh();
}
5.1 вызов this()
  • this()позвонюAnnotationConfigApplicationContextконструктор без аргументов, в то время как вJavaПри наследовании сначала вызывается конструктор родительского класса. Так что он будет звонить первымAnnotationConfigApplicationContextродительский классGeniricApplicationContextконструктор, инициализированный в родительском классеbeanFactory, то есть непосредственноnewвзял одинDefaultListableBeanFactory.
public GenericApplicationContext() {
	this.beanFactory = new DefaultListableBeanFactory();
}
  • существуетthis()прошедшийnew AnnotatedBeanDefinitionReader(this)создал экземплярBeanчитатель, и кBeanDefinitionMapдобавлено в7элементы. пройти черезnew ClassPathBeanDefinitionScanner(this)Создается экземпляр сканера (в дальнейшем сканер не используется).
public AnnotationConfigApplicationContext() {
    // 此处会先调用父类的构造器,即先执行 super(),初始化DefaultListableBeanFactory
    // 初始化了bean的读取器,并向spring中注册了7个spring自带的类,这里的注册指的是将这7个类对应的BeanDefinition放入到到BeanDefinitionMap中
    this.reader = new AnnotatedBeanDefinitionReader(this);
    // 初始化扫描器
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}
  • воплощать в жизньthis.reader = new AnnotatesBeanDefinitionReader(this), он, наконец, вызоветAnnotationConfigUtils.registerAnnotationConfigProcessors(BeanDefinitionRegistry registry,Object source)метод, этот методBeanDefinitionMapдобавлено в7класс, это7сортBeanDefinitionBeanDefinitionВведение может относиться к предыдущему объяснению)RootBeanDefinition, эти классыConfigurationClassPostProcessor,AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor,PersistenceBeanPostProcessor,EventListenerMethodProcessor,DefaultEventListenerFactory.
  • Среди этих семи категорийConfigurationClassPostProcessor,AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessorЭти три класса очень важны.Здесь мы кратко представим функции в следующем коде, а затем напишем отдельные статьи для анализа их функций. Цель этой статьи — сначала представитьSpringЗапустите процесс.
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {
	DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
	// 省略部分代码 ...
	Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
	// 注册ConfigurationClassPostProcessor,这个类超级重要,它完成了对加了Configuration注解类的解析,@ComponentScan、@Import的解析。
	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));
	}
	// 注册AutowiredAnnotationBeanPostProcessor,这个bean的后置处理器用来处理@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));
	}
	// 注册RequiredAnnotationBeanPostProcessor
	if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
	}
	// 注册CommonAnnotationBeanPostProcessor,用来处理如@Resource,@PostConstruct等符合JSR-250规范的注解
	// Check for JSR-250 support, and if present add the 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));
	}
	// 注册PersistenceAnnotationBeanPostProcessor,来用支持JPA
	// Check for JPA support, and if present add the 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));
	}

	// 注册EventListenerMethodProcessor,用来处理方法上加了@EventListener注解的方法
	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));
	}

	// 注册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;
}
  • перечислитьthis.scanner = new ClassPathBeanDefinitionScanner(this)Для инициализации сканера, этот сканер не используется при сканировании пакетов в дальнейшем, предполагаетсяSpringИнициализируется для удовлетворения других сценариев, например: разработчики вручную передаютregister(configClass), который используется при сканировании пакетов.
5.2 register(annotatedClasses)

Класс конфигурации, который будет передан вannotatedClassesанализируется вBeanDefinition(фактический типAnnotatedGenericBeanDefinition), затем вставьтеBeanDefinitionMap, чтобы потом вConfigurationClassPostProcessorЭнергетический анализannotatedClasses,НапримерdemoсерединаAppConfigкласс, только разборAppConfigкласс, чтобы знатьSpringКакие пакеты сканировать (потому что вAppConfigдобавлен класс@ComponentScanПримечание), только если вы знаете, какие пакеты сканировать, вы можете сканировать пакеты, которые необходимо передать.SpringудалосьbeanЧто есть, чтобы мы могли использоватьSpringсоздаватьbean.

5.3 Выполнение метода Refresh()

refresh()метод в целомSpringСердцевина контейнера, выполненная данным способомbeanинстанцирование, инициализация, автопроводка,AOPи другие функции. Давайте взглянемrefresh()Код метода, в код добавлено некоторое личное понимание, и кратко представлена ​​функция каждой строки кода, а подробный анализ нескольких важных методов будет сделан позже.

public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
		// 初始化属性配置文件、检验必须属性以及监听器
		prepareRefresh();
		// Tell the subclass to refresh the internal bean factory.
		// 给beanFactory设置序列化id
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
		// 向beanFactory中注册了两个BeanPostProcessor,以及三个和环境相关的bean
		// 这两个后置处理器为ApplicationContextAwareProcessor和ApplicationListenerDetector
		// 前一个后置处理是为实现了ApplicationContextAware接口的类,回调setApplicationContext()方法,
		// 后一个处理器时用来检测ApplicationListener类的,当某个Bean实现了ApplicationListener接口的bean被创建好后,会被加入到监听器列表中
		prepareBeanFactory(beanFactory);
		try {
			// Allows post-processing of the bean factory in context subclasses.
			// 空方法,由子类实现
			postProcessBeanFactory(beanFactory);
			// 执行所有的BeanFactoryPostProcessor,包括自定义的,以及spring内置的。默认情况下,容器中只有一个BeanFactoryPostProcessor,即:Spring内置的,ConfigurationClassPostProcessor(这个类很重要)
			// 会先执行实现了BeanDefinitionRegistryPostProcessor接口的类,然后执行BeanFactoryPostProcessor的类
			// ConfigurationClassPostProcessor类的postProcessorBeanFactory()方法进行了@Configuration类的解析,@ComponentScan的扫描,以及@Import注解的处理
			// 经过这一步以后,会将所有交由spring管理的bean所对应的BeanDefinition放入到beanFactory的beanDefinitionMap中
			// 同时ConfigurationClassPostProcessor类的postProcessorBeanFactory()方法执行完后,向容器中添加了一个后置处理器————ImportAwareBeanPostProcessor
			invokeBeanFactoryPostProcessors(beanFactory);
			// 注册所有的BeanPostProcessor,因为在方法里面调用了getBean()方法,所以在这一步,实际上已经将所有的BeanPostProcessor实例化了
            // 为什么要在这一步就将BeanPostProcessor实例化呢?因为后面要实例化bean,而BeanPostProcessor是用来干预bean的创建过程的,所以必须在bean实例化之前就实例化所有的BeanPostProcessor(包括开发人员自己定义的)
			// 最后再重新注册了ApplicationListenerDetector,这样做的目的是为了将ApplicationListenerDetector放入到后置处理器的最末端
			registerBeanPostProcessors(beanFactory);
			// Initialize message source for this context.
           // 初始化MessageSource,用来做消息国际化。在一般项目中不会用到消息国际化
			initMessageSource();
			// Initialize event multicaster for this context.
			// 初始化事件广播器,如果容器中存在了名字为applicationEventMulticaster的广播器,则使用该广播器
			// 如果没有,则初始化一个SimpleApplicationEventMulticaster
            // 事件广播器的用途是,发布事件,并且为所发布的时间找到对应的事件监听器。
			initApplicationEventMulticaster();

			// Initialize other special beans in specific context subclasses.
			// 执行其他的初始化操作,例如和SpringMVC整合时,需要初始化一些其他的bean,但是对于纯spring工程来说,onFresh方法是一个空方法
			onRefresh();

			// Check for listener beans and register them.
			// 这一步会将自定义的listener的bean名称放入到事件广播器中
			// 同时还会将早期的ApplicationEvent发布(对于单独的spring工程来说,在此时不会有任何ApplicationEvent发布,但是和springMVC整合时,springMVC会执行onRefresh()方法,在这里会发布事件)
			registerListeners();
			// 实例化剩余的非懒加载的单例bean(注意:剩余、非懒加载、单例)
            // 为什么说是剩余呢?如果开发人员自定义了BeanPosrProcessor,而BeanPostProcessor在前面已经实例化了,所以在这里不会再实例化,因此这里使用剩余一词
			finishBeanFactoryInitialization(beanFactory);
			// 结束refresh,主要干了一件事,就是发布一个事件ContextRefreshEvent,通知大家spring容器refresh结束了。
			finishRefresh();
		}
		catch (BeansException ex) {
			// 出异常后销毁bean
			destroyBeans();
			// Reset 'active' flag.
			cancelRefresh(ex);
			// Propagate exception to caller.
			throw ex;
		}
		finally {
           // 在bean的实例化过程中,会缓存很多信息,例如bean的注解信息,但是当单例bean实例化完成后,这些缓存信息已经不会再使用了,所以可以释放这些内存资源了
			resetCommonCaches();
		}
	}
}

6. Метод обновления()

  • существуетrefresh()Среди методов наиболее важными являютсяinvokeBeanFactoryPostProcessors(beanFactory)а такжеfinishBeanFactoryInitialization(beanFactory). Другие методы относительно просты.В основном анализируются следующие два метода.Для функций других методов вы можете обратиться к комментариям в исходном коде выше.
6.1 invokeBeanFactoryPostProcessors()
  • Цель этого метода — выполнить всеBeanFactoryPostProcessor,из-заSpringбудет иметь встроенныйBeanFactoryPostProcessor,СейчасConfigurationClassPostProcessor(Если разработчик не настраивает, по умолчанию стоит только этотBeanFactoryPostProcessor), этот постпроцессор проанализирует всеSpringуправляемый контейнерBean, разобрать их наBeanDefinitionЗатем положите его вBeanFactoryизBeanDefinitionMapсередина.
  • Этот метод в конечном итоге будет вызываться дляPostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()метод, основная роль заключается в выполнении всехBeanFactoryPostProcessorизpostProcessorBeanFactory()метод.BeanFactoryPostProcessorОн разделен на два случая, один из которых является прямой реализациейBeanFactoryPostProcessorКласс интерфейса, другой случай - реализоватьBeanDefinitionRegistryPostProcessorинтерфейс(BeanDefinitionRegistryPostProcessorнаследоватьBeanFactoryPostProcessorинтерфейс).
    UML图
  • Выполнить всеBeanDefinitionRegistryPostProcessorизpostProcessorBeanDefinitionRegistry()метод, а затем выполнитьBeanFacotryPostProcessorизpostProcessorBeanFactory()метод.
public interface BeanFactoryPostProcessor {
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
  • по умолчанию,Springимеет встроенныйBeanFactoryPostProcessor,который:ConfigurationClassPostProcessorкласс, реализующийBeanDefinitionRegistryPostProcessorкласс, поэтому будет выполнятьсяConfigurationClassPostProcessor.postProcessorBeanDefinitionRegistry,ConfigurationClassPostProcessorизUMLКартина как выше (удалены некоторые неважные отношения наследования)
6.2 registerBeanPostProcessors()
  • Что делает этот метод, так это находит всеBeanPostProcessor, затем поместите этиBeanPostProcessorсоздать экземпляр (будет вызыватьgetBean()метод,getBean()Основная логика метода заключается в том, что еслиbeanСуществовать вBeanFactoryв, вернутьсяbean; если он не существует, он будет создан. будет подробно проанализировано позжеgetBean()логика исполнения). положить этиPostProcessorПосле создания, наконец, положить вBeanFactoryизbeanPostProcessorsв свойствах.
  • Вопрос: Как найти всеBeanPostProcessor? включатьSpringВстроенный и определяемый разработчиком.
  • из-заrefresh()метод, будет выполнен первымinvokeBeanFactoryPostProcessor()метод, так что все пользовательскиеBeanPostProcessorКлассы были отсканированы и разобраны наBeanDefinition(А кто делал сканирование и парсинг?ConfigurationClassPostProcessorсделано), депозит вBeanFactoryизBeanDefinitionMap, так что здесь мы можем найти всеBeanPostProcessor, то черезgetBean()Все экземпляры создаются, и, наконец, экземпляры объектов добавляются вBeanFactoryизbeanPostProcessorsимущество, имущество представляет собойListсобирать.
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
  • Наконец-то перерегистрировалсяApplicationListenerDetector, целью этого являетсяApplicationListenerDetectorв конец постпроцессора
  • registerBeanPostProcessor()Последний звонокPostProcessorRegistrationDelegate.registerBeanPostProcessors(), следующееPostProcessorRegistrationDelegate.registerBeanPostProcessors()код метода
public static void registerBeanPostProcessors(
		ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

	// 从BeanDefinitionMap中找出所有的BeanPostProcessor
	String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
	// ... 省略部分代码 ...

	// 分别找出实现了PriorityOrdered、Ordered接口以及普通的BeanPostProcessor
	for (String ppName : postProcessorNames) {
		if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
			// 此处调用了getBean()方法,因此在此处就会实例化出BeanPostProcessor
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			priorityOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
			orderedPostProcessorNames.add(ppName);
		}
		else {
			nonOrderedPostProcessorNames.add(ppName);
		}
	}

	// First, register the BeanPostProcessors that implement PriorityOrdered.
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	// 将实现了PriorityOrdered接口的BeanPostProcessor添加到BeanFactory的beanPostProcessors集合中
	registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

	// 下面这部分代码与上面的代码逻辑一致,是将实现了Ordered接口以及普通的BeanPostProcessor实例化以及添加到beanPostProcessors结合中,逻辑与处理PriorityOrdered的后置处理器一样
	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);
	
	// Now, register all regular 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);
	
	// Finally, re-register all internal BeanPostProcessors.
	sortPostProcessors(internalPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, internalPostProcessors);
	
	// Re-register post-processor for detecting inner beans as ApplicationListeners,
	// moving it to the end of the processor chain (for picking up proxies etc).
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));

	// 最后将ApplicationListenerDetector这个后置处理器一样重新放入到beanPostProcessor中,这样做的目的是为了将其放入到后置处理器的最末端
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
  • Как видно из приведенного выше исходного кода,BeanPostProcessorПриоритет существует, реализованPriorityOrderedИнтерфейс имеет наивысший приоритет, за ним следуетOrderedинтерфейс, и, наконец, нормальныйBeanPostProcessor. Наивысший приоритет будет размещен первымbeanPostProcessorsФронт этого задайте, чтобы при выполнении постпроцессор с наивысшим приоритетом выполнялся первым (т.к.ListКоллекции заказаны).
  • Таким образом, в практических приложениях, если мы сталкиваемся с необходимостью отдавать приоритет определенномуBeanPostProcessorреализация, вы можете это сделатьPriorityOrderedинтерфейс илиOrderedинтерфейс.
6.3 initMessageSource()
  • Он используется для поддержки интернационализации сообщений, а знания, связанные с интернационализацией, сейчас не используются в общих проектах.
6.4 initApplicationEventMulticaster()

Этот метод инициализирует средство вещания событий, если контейнер существует.beanNameзаapplicationEventMulticasterвещатель, используйте этот вещатель; если нет, инициализируйте одинSimpleApplicationEventMulticaster. Вещатель событий используется для распространения событий приложения, этот класс будет содержать все прослушиватели событий (ApplicationListener), когда естьApplicationEventКогда событие публикуется, прослушиватель событий может получить интересующие его события в соответствии с типом события.ApplicationListener.

  • initApplicationEventMulticaster()Исходный код метода выглядит следующим образом (некоторая информация журнала опущена):
protected void initApplicationEventMulticaster() {
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	// 判断spring容器中是否已经存在beanName = applicationEventMulticaster的事件广播器
	// 例如:如果开发人员自己注册了一个
	// 如果存在,则使用已经存在的;否则使用spring默认的:SimpleApplicationEventMulticaster
	if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
		this.applicationEventMulticaster =
				beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
	}
	else {
		this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
		beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
	}
}
6.5 onRefresh()

выполнять другие операции инициализации, такие как иSpringMVCПри интеграции нужно инициализировать некоторые другиеbean, а для чистогоSpringДля машиностроения,onRefresh()метод является пустым методом.

6.6 registerListeners()

Этот шаг позволит настроитьlistenerизbeanимя в вещатель события вместе с ранееApplicationEventвыпуск (для отдельныхSpringИнженерии, в это время не будетApplicationEventпост, но иSpringMVCПри интеграции,SpringMVCбудет выполнятьonRefresh()метод, в котором публикуются события). Исходный код метода выглядит следующим образом:

protected void registerListeners() {
	// Register statically specified listeners first.
	for (ApplicationListener<?> listener : getApplicationListeners()) {
  getApplicationEventMulticaster().addApplicationListener(listener);
	}

	// 从BeanFactory中找到所有的ApplicationListener,但是不会进行初始化,因为需要在后面bean实例化的过程中,让所有的BeanPostProcessor去改造它们
	String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
	for (String listenerBeanName : listenerBeanNames) {
		// 将事件监听器的beanName放入到事件广播器中
		getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
	}

	// 发布早期的事件(纯的spring工程,在此时一个事件都没有)
	Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
	this.earlyApplicationEvents = null;
	if (earlyEventsToProcess != null) {
		for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
			getApplicationEventMulticaster().multicastEvent(earlyEvent);
		}
	}
}
6.7 finishBeanFactoryInitialization()

Этот метод очень важен, он завершает все незагруженные синглтоны.BeanСоздание и инициализация , заполнение свойств и решение таких проблем, как круговые зависимости.

  • (Обратите внимание, что процессы инстанцирования и инициализации объектов намеренно разделены здесь, потому что вSpringСоздайтеBeanв процессе сначалаBeanОбъекты создаются посредством отражения, затем проходят через постпроцессор (BeanPostProcessor) для присвоения значений свойствам объекта. Таким образом, конкретизация здесь относится кBeanСоздано, инициализация относится кbeanпередача имущества).
  • finishBeanFactoryInitialization()Код метода выглядит следующим образом:beanсоздаются и инициализируются вbeanFactory.preInstantiateSingletons()реализовано в.
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
	// 初始化转换服务
	if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
			beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
		beanFactory.setConversionService(
				beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
	}
	// 如果前面没有注册一个类似于PropertyPlaceholderConfigurer后置处理器的bean,那么在这儿会注册一个内置的属性后置处理器
	// 这儿主要是处理被加了注解的属性
	if (!beanFactory.hasEmbeddedValueResolver()) {
		beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
	}
	// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
	String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
	for (String weaverAwareName : weaverAwareNames) {
		getBean(weaverAwareName);
	}
	beanFactory.setTempClassLoader(null);
	// 将BeanFactory的configurationFrozen属性设置为true,给frozenBeanDefinitionNames属性赋值
	// 目的是为了不让在其他的地方在修改bean的BeanDefinition
	beanFactory.freezeConfiguration();

	// Instantiate all remaining (non-lazy-init) singletons.
	// 实例化剩下所有的非懒加载的单例
	beanFactory.preInstantiateSingletons();
}
6.7.1 Метод preInstantiateSingletons()
  • Метод сначала определитbeanэтоFactoryBean, и следует ли создавать экземпляр немедленноFactoryBeanизgetObject()Возвращаемый объект, но в конечном итоге оба вызываютсяgetBean()метод создания экземпляра объекта. существуетBeanПосле завершения создания и инициализации он будет судитьBeanБыло ли это реализованоSmartSingletonInitializingинтерфейс, если он реализован, интерфейсafterSingletonInstantiated()метод.
  • Tips: упомянуто здесьFactoryBean,нетBeanFactory. Имена этих двух очень похожи, но функции очень разные Заинтересованные друзья могут сначалаGoogleПроверьте соответствующие знания. Вот краткое введение, а в будущем будет написана отдельная статья.FactoryBean, и пройтиFactoryBeanразбиратьSpringа такжеMyBatisПринципы интеграции.
  • FactoryBeanявляется интерфейсом, и класс реализации этого интерфейса будет регистрировать дваbean, один — реализовать объект типа, представленного самим классом, а другой — переопределитьFactoryBeanв интерфейсеgetObject()метод возвращенbean. В следующем примере: два будут зарегистрированы в контейнереbean,одинMapperFactoryBeanсам, одинUserMapper.
@Component
public class MapperFactoryBean implements FactoryBean {
    @Override
    public Object getObject() throws Exception {
        return new UserMapper();
    }

    @Override
    public Class<?> getObjectType() {
        return UserMapper.class;
    }
}
  • из-заbeanПроцесс создания слишком сложен, и исходный код будет проанализирован вместе с блок-схемой позже.preInstantiatedSingletons()Схема выполнения метода выглядит следующим образом.
    preInstantiatedSingletons()方法流程图
  • preInstantiatedSingletons()код показывает, как показано ниже
public void preInstantiateSingletons() throws BeansException {
	if (logger.isDebugEnabled()) {
		logger.debug("Pre-instantiating singletons in " + this);
	}
	List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
	// Trigger initialization of all non-lazy singleton beans...
	for (String beanName : beanNames) {
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			// 判断是否是factoryBean,如果是FactoryBean,则进行FactoryBean原生的实例化(非getObject()方法对应的对象)。
			// 还需要判断它是否立即实例化getObject()返回的对象,根据SmartFactoryBean的isEagerInit()的返回值判断是否需要立即实例化
			if (isFactoryBean(beanName)) {
				// 首先实例化BeanFactory的原生对象,然后再根据isEagerInit()判断是否实例化BeanFactory中getObject()返回的类型的对象
				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());
					}
					// 如果isEagerInit为true,则立即实例化FactoryBean所返回的类型的对象
					if (isEagerInit) {
						getBean(beanName);
					}
				}
			}
			else {
				getBean(beanName);
			}
		}
	}
	// 在bean实例化以及属性赋值完成后,如果bean实现了SmartInitializingSingleton接口,则回调该接口的方法
	for (String beanName : beanNames) {
		Object singletonInstance = getSingleton(beanName);
		if (singletonInstance instanceof SmartInitializingSingleton) {
			final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
			if (System.getSecurityManager() != null) {
				AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
					smartSingleton.afterSingletonsInstantiated();
					return null;
				}, getAccessControlContext());
			}
			else {
				smartSingleton.afterSingletonsInstantiated();
			}
		}
	}
}
  • Найдено из приведенного выше исходного кода, будь тоFactoryBeanвсе еще обычныйBean, в конце концов звонитgetBean()метод созданияbean.
6.7.2 getBean()
  • getBean()метод вызоветdoGetBean()метод.
public Object getBean(String name) throws BeansException {
	return doGetBean(name, null, null, false);
}
6.7.3 doGetBean()
  • существуетdoGetBean()метод, он будет получен сначала из кеша (то есть изsingletonObjectsэтоmapПолучить из коллекции, зачем сначала брать из тайника? потому что изSpringКонтейнер получает объекты и создает объекты черезgetBean()метод, для одноэлементного объекта объект будет создан только один раз, затем сначала получите объект из кеша, если он существует, нет необходимости создавать новый, что гарантирует, что одноэлементный объект создается только один раз). Если он существует в кеше, вызовитеgetObjectForBeanInstance()метод, затем возвратbean. Если его нет в кеше, продолжайте выполнение.
  • затем получитьBeanсоответствующийBeanDefinitionобъект. Тогда судитеbeanЕсть ли зависимость,String[] dependsOn = mbd.getDependsOn(), если есть зависимый объект, сначала будет создан экземпляр зависимого объекта.
  • После создания зависимого объекта он будет вызыватьсяgetSingleton(beanName,lambda)метод, вторым параметром этого метода являетсяlambdaвыражение, которое фактически создаетbeanЛогика находится в теле метода выражения, т.е.createBean()метод,createBean()метод будет созданbean, затем вgetSingleton(beanName,lambda)метод создаст завершенныйbeanдепозит вsingletonObjectsв свойствах.createBean()анализ позже.
  • Создано на предыдущем шагеbean, он все равно в конечном итоге вызоветgetObjectForBeanInstance(). Логика этого метода относительно проста, сначала оценитеbeanэтоFactoryBean, если нет, вернитесь напрямуюbean; если так, то судитеbeanNameНачинается ли он с символа &, если да, то это означает, что полученныйFactoryBeanсобственный объект, возврат напрямуюbean; если он не начинается с амперсанда, он вернетFactoryBeanизgetObject()Объект возвращаемого значения метода.
  • doGetBean()Код метода выглядит следующим образом
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
		@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
	final String beanName = transformedBeanName(name);
	Object bean;
	// Eagerly check singleton cache for manually registered singletons.
	Object sharedInstance = getSingleton(beanName);
	if (sharedInstance != null && args == null) {
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}
	else {
		// Fail if we're already creating this bean instance:
		// We're assumably within a circular reference.
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}
		// Check if bean definition exists in this factory.
		BeanFactory parentBeanFactory = getParentBeanFactory();
		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
			// Not found -> check parent.
			String nameToLookup = originalBeanName(name);
			if (parentBeanFactory instanceof AbstractBeanFactory) {
				return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
						nameToLookup, requiredType, args, typeCheckOnly);
			}
			else if (args != null) {
				// Delegation to parent with explicit args.
				return (T) parentBeanFactory.getBean(nameToLookup, args);
			}
			else {
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			}
		}
		if (!typeCheckOnly) {
			// 标记bean为已创建
			// 并清除beanDefinition的缓存(mergedBeanDefinitions)
			markBeanAsCreated(beanName);
		}
		try {
			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			// 检查bean是否是抽象类
			checkMergedBeanDefinition(mbd, beanName, args);
			// Guarantee initialization of beans that the current bean depends on.
			// 保证当前bean所依赖的bean初始化
			String[] dependsOn = mbd.getDependsOn();
			if (dependsOn != null) {
				for (String dep : dependsOn) {
					// isDependent()方法用来判断dep是否依赖beanName
					if (isDependent(beanName, dep)) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
					}
					// 保存下依赖关系
					registerDependentBean(dep, beanName);
					try {
						getBean(dep);
					}
					catch (NoSuchBeanDefinitionException ex) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
					}
				}
			}
			// Create bean instance.
			if (mbd.isSingleton()) {
				// 此时在getSingleton方法中传入了一个lambda表达式,
				// 此时不会立即执行lambda表达式,而是在调用这个lambda表达式的getObject()方法时才开始执行lambda的方法体
				sharedInstance = getSingleton(beanName, () -> {
					try {
						return createBean(beanName, mbd, args);
					}
					catch (BeansException ex) {
						destroySingleton(beanName);
						throw ex;
					}
				});
				bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			}

			else if (mbd.isPrototype()) {
				// It's a prototype -> create a new instance.
				Object prototypeInstance = null;
				try {
					beforePrototypeCreation(beanName);
					prototypeInstance = createBean(beanName, mbd, args);
				}
				finally {
					afterPrototypeCreation(beanName);
				}
				bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			}
			else {
				String scopeName = mbd.getScope();
				final Scope scope = this.scopes.get(scopeName);
				if (scope == null) {
					throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
				}
				try {
					Object scopedInstance = scope.get(beanName, () -> {
						beforePrototypeCreation(beanName);
						try {
							return createBean(beanName, mbd, args);
						}
						finally {
							afterPrototypeCreation(beanName);
						}
					});
					bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
				}
				catch (IllegalStateException ex) {
					throw new BeanCreationException(beanName,
							"Scope '" + scopeName + "' is not active for the current thread; consider " +
							"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
							ex);
				}
			}
		}
		catch (BeansException ex) {
			cleanupAfterBeanCreationFailure(beanName);
			throw ex;
		}
	}
	if (requiredType != null && !requiredType.isInstance(bean)) {
		try {
			T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
			if (convertedBean == null) {
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
			return convertedBean;
		}
		catch (TypeMismatchException ex) {
			throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
		}
	}
	return (T) bean;
}
  • getObjectForBeanInstance()Цель метода состоит в том, чтобыbeanNameсудить значит вернутьсяFactoryBeanсобственный объект илиgetObject()Объект, возвращаемый методом.beanNameНачните со знака &, это означает возвратFactoryBeanсобственный объект, в противном случае возвратgetObject()Объект, возвращаемый методом.
protected Object getObjectForBeanInstance(
		Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
	if (BeanFactoryUtils.isFactoryDereference(name)) {
		if (beanInstance instanceof NullBean) {
			return beanInstance;
		}
		if (!(beanInstance instanceof FactoryBean)) {
			throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
		}
	}

	// 如果不是一个FactoryBean对象或者是获取FactoryBean的原生对象(原生对象指的是beanName是以&开头)
	// 此时可以直接返回bean
	if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
		return beanInstance;
	}

	// 如果是获取FactoryBean的getObject()方法返回的类型对象,则需要进入到如下逻辑
	// 对于getObject()方法,它返回的对象是在在第一次调用getObject方法时进行实例化的,实例化完成以后,会将结果缓存在factoryBeanObjectCache中
	Object object = null;
	if (mbd == null) {
		object = getCachedObjectForFactoryBean(beanName);
	}
	if (object == null) {
		// Return bean instance from factory.
		FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
		// Caches object obtained from FactoryBean if it is a singleton.
		if (mbd == null && containsBeanDefinition(beanName)) {
			mbd = getMergedLocalBeanDefinition(beanName);
		}
		boolean synthetic = (mbd != null && mbd.isSynthetic());
		// 获取FactoryBean返回的对象
		object = getObjectFromFactoryBean(factory, beanName, !synthetic);
	}
	return object;
}
6.7.4 createBean()
  • doGetBean()в конце концов позвонитcreateBean()создаватьbean.
  • createBean()В коде метода в основном есть две строки основного кода:
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
  • resolveBeforeInstantiation()метод вbeanВызывается перед созданием экземпляра, постпроцессор выполняется в этом методе.InstantiationAwareBeanPostProcessorизpostProcessBeforeInstantiation()метод, вbeanперед созданием экземпляраbeanдля обработки. Значение этой точки расширения очень важно.SpringизAOPЭто реализовано здесь, заинтересованные друзья могут прочитатьAnnotationAwareAspectJAutoProxyCreatorИсходный код этого класса будет разобран позже в отдельной статье.
  • еслиresolveBeforeInstantiation()Возвращаемое значение неnull, результат возвращается напрямую. еслиnull, он продолжит выполнение методаdoCreateBean(). существуетdoCreateBean()метод, осуществляемыйBeanсоздание экземпляров, присвоение атрибутов, инициализация и другие операции.
  • createBean()Блок-схема метода
    createBean()方法流程图
  • createBean()исходный код метода
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
		throws BeanCreationException {
	RootBeanDefinition mbdToUse = mbd;
	// Make sure bean class is actually resolved at this point, and
	// clone the bean definition in case of a dynamically resolved Class
	// which cannot be stored in the shared merged bean definition.
	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 {
		// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
		// 第一次调用后置处理器(执行所有InstantiationAwareBeanPostProcessor的子类)
		// 如果InstantiationAwareBeanPostProcessor的子类的postProcessBeforeInstantiation()方法返回值不为空,表示bean需要被增强,
		// 此时将不会执行后面的逻辑,AOP的实际应用就是在这儿实现的
		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 {
		// 第二次执行后置处理器的入口
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		if (logger.isDebugEnabled()) {
			logger.debug("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);
	}
}
6.7.5 doCreateBean()
  • doCreateBean()метод будет выполняться через отражениеBeanсозданиеbeanЗаполнить атрибуты (при заполнении атрибутов решается проблема циклических зависимостей), и, наконец,BeanМетоды, связанные с инициализацией обратного вызова, например:BeanPostProcessor.postProcessBeforeInilization(),InilizaingBean.afterPropertiesSet(),ДатьbeanнастроенinitMethod()метод иBeanPostProcessor.postProcessAfterInilization().
  • doCreateBean()Схема выполнения следующая: ![блок-схема метода doCreateBean()]Боюсь 1-solve.byte IMG.com/to S-talent-i-he 2…)
  • doCreateBean()Код метода (с удаленным кодом) выглядит следующим образом:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
		throws BeanCreationException {
	// Instantiate the bean.
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
		// 实例化bean(第二次执行后置处理器的入口),第二次执行后置处理器,主要是为了推断出实例化Bean所需要的构造器
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	final Object bean = instanceWrapper.getWrappedInstance();
	Class<?> beanType = instanceWrapper.getWrappedClass();
	if (beanType != NullBean.class) {
		mbd.resolvedTargetType = beanType;
	}
	// 此时bean对象已经创建成功,但是没有设置属性和经过其他后置处理器处理
	// Allow post-processors to modify the merged bean definition.
	synchronized (mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
			try {
				// 第三次执行后置处理器,缓存bean的注解元数据信息(用于后面在进行属性填充时使用)
				// 这一步对于CommonAnnotationBeanPostProcessor、AutowiredAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor这一类处理器
				// 主要是将bean的注解信息解析出来,然后缓存到后置处理器中的injectionMetadataCache属性中
				// 而对于ApplicationListenerDetector处理器,而是将bean是否是单例的标识存于singletonNames这个Map类型的属性中
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			}
			mbd.postProcessed = true;
		}
	}
	// 判断一个bean是否放入到singletonFactories中(提前暴露出来,可以解决循环依赖的问题)
	boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
			isSingletonCurrentlyInCreation(beanName));
	if (earlySingletonExposure) {
		// 第四次出现后置处理器
		// 获取提前暴露的对象,可以解决循环引用的问题,实际上提前暴露出来的bean是放入到了singletonFactories中,key是beanName,value是一个lambda表达式
		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
	}
	// Initialize the bean instance.
	Object exposedObject = bean;
	try {
		// 填充属性,第五次、第六次后置处理器入口
		populateBean(beanName, mbd, instanceWrapper);
		// 第七次、第八次执行后置处理器入口
		exposedObject = initializeBean(beanName, exposedObject, mbd);
	}
	catch (Throwable ex) {
	}
	return exposedObject;
}
  • createBeanInstance()Когда объект создается посредством отражения, постпроцессор будет выполняться первым, а при вызове постпроцессораdeternineCondidateConstructors()метод, чтобы определить, какой конструктор использовать для созданияBean, типичные репрезентативные классыAutowiredAnnotationBeanPostProcessor.
  • beanПосле создания путем отражения постпроцессор будет вызван снова.MergedBeanDefinitionPostProcessor.postProcessMargedBeanDefinition()метод, цель выполнения постпроцессора на этом шаге состоит в том, чтобы выяснить добавленную@Autowired,@Resourceи другие атрибуты и методы аннотации, а затем кэшировать эту информацию аннотаций вinjectionMetadataCacheсвойств, что удобно для последующего использования.beanЭтап инициализации (этап присвоения атрибутов), согласно@Autowiredи другие аннотации для автоматической сборки. Репрезентативный постпроцессор этого шага имеетAutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor

AutowiredAnnotationBeanPostProcessorиспользуется для обработкиSpringпредоставлены аннотации иJSR-330Некоторые аннотации в , такие как:@Autowired,@Value,@Inject.CommonAnnotationBeanPostProcessorиспользуется для обработкиJSR-250аннотации в , такие как@Resource,@PostConstruct,@PreDestroy.

  • Полуфабрикат будетbean(Потому что это еще не даноbeanПрисвоение атрибута , автоматическая сборка не завершена, поэтому он называется полуфабрикатом) вDefaultSingletonBeanRegistryКатегорияsingletonFactoriesсвойств,singletonFactoriesсобственность - этоMap,keyзаbeanName, значениеObjectFactoryтипа (на самом делеlambdaвыражение), при вызовеObjectFactoryизgetObject()метод будет выполнятьсяlambdaТело метода выражения в текущем сценарииlambdaКод выражения выглядит следующим образом, который фактически выполняется один разBeanпостпроцессор. Цель этого шага – решитьbeanКак решить круговую зависимость между ними, будет проанализировано позже.
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
	Object exposedObject = bean;
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
				SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                // 调用后置处理的方法获取bean早期暴露出来的bean对象(半成品)
				exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
			}
		}
	}
	return exposedObject;
}
  • затем выполняется дляpopulateBean()метод, в котором он выполняется дваждыBeanПостпроцессор, первый раз, когда постпроцессор выполняется, должен судитьBeanНужно ли продолжать заполнять свойства, еслиInstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()метод возвращенfalse, значит заполнение атрибута не производится,beanне будет продолжаться@AutowiredДождитесь автоматического процесса сборки,populateBean()Метод заканчивается немедленно. Если вернутьсяtrue, будет выполнено следующее заполнение атрибута, то есть будет выполнен второй постпроцессор,InstantiationAwareBeanPostProcessor.postProcessPropertyValue()метод, главным героем этого шага являетсяAutowiredAnnotationBeanPostProcessorа такжеCommonAnnotationBeanPostBeanPostProcessor, они будут кэшироваться вinjectionMetadataCacheаннотационная информация для автоматической сборки.
  • после выполненияpopulateBean()Следующим шагом после метода является выполнениеinitializeBean()метод, то есть войти в фазу инициализации. существуетinitializeBean()метод, выполнить первымinvokeAwareMethods()метод, который выполняетAwareМетоды интерфейса, такие как:BeanNameAware,BeanClassLoaderAware,BeanFactoryAware. затем сделать все сноваBeanпостпроцессорBeanPostProcessor.postProcessBeforeInitialization()метод. Затем выполнитеinvokeInitMethods()метод, вinvokeInitMethods()метод, выполнитInitializingBeanизafterPropertiesSet()методы и определенияbeanобычайinitMethod()метод. последняя казньbeanпостпроцессор,BeanPostProcessor.postProcessAfterInitialization().
  • слишком далекоbeanПроцесс инстанцирования и инициализации завершен, и созданныйbeanбудет возвращено, если это синглтонbean, который в конечном итоге будет сохранен вDefaultSingletonBeanRegistryизsingletonObjectsсередина.
6.8 finishRefresh()
  • Выполните этот шаг,SpringЗапуск контейнера в основном завершен, на данный моментBeanБыл создан и автоматически подключен. воплощать в жизньfinishRefresh()метод, для контейнераrefresh()В конце проделайте еще какие-нибудь операции, например: опубликуйтеContextRefreshedEventсобытие, так что когда мы хотим, чтобы контейнерrefreshВыполнив некоторую специальную логику, вы можете прослушатьContextRefreshedEventсобытие для достижения.SpringСуществует четыре встроенных контекста и контекста приложения (ApplicationContextEvent) связанные события:ContextRefreshedEvent,ContextStartedEvent,ContextStopedEvent,ContextClosedEvent.
protected void finishRefresh() {
    clearResourceCaches();
    initLifecycleProcessor();
    getLifecycleProcessor().onRefresh();
    // 发布ContextRefreshedEvent
    publishEvent(new ContextRefreshedEvent(this));
    LiveBeansView.registerApplicationContext(this˛);
}
6.9 resetCommonCaches()

Наконец вrefresh()методfinallyблок операторов, выполненныйresetCommonCaches()метод. потому что создано ранееbeanкогда для синглтонаbeanИнформация метаданных кэшируется, а синглтонbeanПосле того, как контейнер будет запущен, он больше не будет создан, поэтому кешированная информация больше не нужна, здесь она очищается, чтобы освободить часть памяти.

protected void resetCommonCaches() {
    ReflectionUtils.clearCache();
    AnnotationUtils.clearCache();
    ResolvableType.clearCache();
    CachedIntrospectionResults.clearClassLoader(getClassLoader());
}

7. Жизненный цикл фасоли

  • сверхуSpringИз анализа исходного кода видно, что в процессе запускаbeanПроцесс создания самый сложный, в процессе создания всего 8 вызовов до и послеBeanPostPorcessor(на самом деле вbeanВсего за весь жизненный цикл будет9Постпроцессор вызывается в девятый раз вbeanстадия разрушения. )
  • комбинироватьSpringисходный код, синглтонbeanЖизненный цикл можно представить в виде следующей картины
    Bean生命周期图

8. Резюме

  • В этой статье описываетсяSpringпроцесс запуска черезAnnotationConfigApplicationContextНачиная с параметризованного метода построенияthis()Методы иrefresh()метод. существуетthis()инициализируется вBeanFactory,СейчасDefaultListableBeanFactory; Семь затем добавили к построенному суднуbean, которая включает в себяConfigurationClassPostProcessor.
  • существуетrefresh()В методе основное внимание уделяется анализуinvokeBeanFactoryPostProcessor()Методы иfinishBeanFactoryInitialization()метод.
  • существуетinvokeBeanFactoryPostProcessor()метод, черезConfigurationClassPostProcessorКласс сканирует все сданныеSpringуправляемый класс, и будетclassФайл анализируется в соответствующийBeanDefinition.
  • существуетfinishBeanFactoryInitialization()В методе завершена неленивая загрузка синглтонаBeanОперации создания и инициализации , основной процессgetBean()——>doGetBean()——>createBean()——>doCreateBean(). существуетbeanВсего за время создания8второсортныйBeanPostProcessor, во время выполнения этих постпроцессоров завершитьAOPреализация,beanАвто-проводка, присвоение атрибутов и другие операции.
  • Наконец, через блок-схему, подытоженнуюSpringсинглтонBeanжизненный цикл.

9. Планирование

Эта статья в основном знакомитSpringОднако конкретные детали реализации в некоторых местах не анализировались, поэтому план последующего анализа исходного кода Spring таков:

  • ConfigurationClassPostProcessorКак класс сканирует пакет и анализирует класс конфигурации.
  • @ImportАннотация и@EnableПринцип реализации аннотации серий
  • JDKдинамический прокси сCGLIBиграет роль
  • FactoryBeanИспользование и анализ исходного кода
  • AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessorКак реализовать автоматическую сборку,SpringКак разрешить циклические зависимости
  • AOPПринцип реализации
  • SpringBootАнализ исходного кода

10. Рекомендуемые инструменты мониторинга производительности

  • Наконец, рекомендуется инструмент мониторинга производительности с открытым исходным кодом —Pepper-Metrics

адрес:GitHub.com/live-actioncool/pep… GitHub Pepper-MetricsЭто компонент с открытым исходным кодом, разработанный двумя коллегами, сидящими напротив меня. Основная функция состоит в том, чтобы соединяться с общими компонентами с открытым исходным кодом относительно легким способом (jedis/mybatis/motan/dubbo/servlet) интегрированы, собраны и вычисленыmetrics, а также поддерживает вывод в журналы и преобразование в различные форматы данных, совместимые с базой данных временных рядов, поддерживаяgrafana dashboardПокажи дружелюбно. Основные документы в проекте завершены, и все они основаны наSPIРазработанная расширяемая архитектура упрощает разработку новых подключаемых модулей. другой на основеdocker-composeнезависимостьdemoПроекты могут быстро начать наборdemoПример эффекта просмотраhttps://github.com/zrbcool/pepper-metrics-demo. Если вы найдете это полезным, пожалуйста, дайтеstar, и приглашаю всех принять участие в разработке, спасибо :)


Добро пожаловать, чтобы отсканировать QR-код ниже и подписаться на общедоступную учетную запись WeChat: Cainiao Fei Ya Fei Читайте больше исходного кода, больше не для программирования поисковых систем

微信公众号:菜鸟飞呀飞