Spring Boot - IOC(三)
本篇解析6-10步骤:
// Register bean processors that intercept bean creation.
//4.7.6 注册Bean的后置处理器
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
//4.7.7 初始化MessageSource(SpringMVC)
initMessageSource();
// Initialize event multicaster for this context.
//4.7.8 初始化事件派发器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
//4.7.9、4.8 子类的多态onRefresh
onRefresh();
// Check for listener beans and register them.
//4.7.10 注册监听器
registerListeners();
6. registerBeanPostProcessors:注册 BeanPostProcessor
(源码较长,关键注释已标注在源码中)
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// 这次拿的接口类型是BeanPostProcessor,并且创建了更多的List,分别存放不同的PostProcessor
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
// 根据PriorityOrdered、Ordered接口,对这些BeanPostProcessor进行归类
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
// MergedBeanDefinitionPostProcessor类型的后置处理器被单独放在一个集合中,说明该接口比较特殊
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.
// 注册实现了PriorityOrdered的BeanPostProcessor
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
// 注册实现了Ordered接口的BeanPostProcessor
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.
// 注册普通的BeanPostProcessor
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.
// 最最后,才注册那些MergedBeanDefinitionPostProcessor
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).
// 手动加了一个ApplicationListenerDetector,它是一个ApplicationListener的检测器
// 这个检测器用于在最后检测IOC容器中的Bean是否为ApplicationListener接口的实现类,如果是,还会有额外的作用
// 实际上它并不是手动加,而是重新注册它,让他位于所有后置处理器的最末尾位置
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
发现这段套路与前面看到的注册 BeanFactoryPostProcessor
极其类似!
这里面有几个特殊的组件,着重看一眼:
6.1 MergedBeanDefinitionPostProcessor
它是一个接口,它的文档注释原文翻译:
Post-processor callback interface for merged bean definitions at runtime. BeanPostProcessor implementations may implement this sub-interface in order to post-process the merged bean definition (a processed copy of the original bean definition) that the Spring BeanFactory uses to create a bean instance. The postProcessMergedBeanDefinition method may for example introspect the bean definition in order to prepare some cached metadata before post-processing actual instances of a bean. It is also allowed to modify the bean definition but only for definition properties which are actually intended for concurrent modification. Essentially, this only applies to operations defined on the RootBeanDefinition itself but not to the properties of its base classes.
在运行时用于合并bean定义的后处理器回调接口。 BeanPostProcessor
实现可以实现此子接口,以便对Spring BeanFactory
用于创建bean实例的合并bean定义(原始bean定义的已处理副本)进行后处理。
postProcessMergedBeanDefinition
方法可以例如内省bean定义,以便在对bean的实际实例进行后处理之前准备一些缓存的元数据。还允许修改bean定义,但只允许修改实际上用于并行修改的定义属性。本质上,这仅适用于 RootBeanDefinition
本身定义的操作,不适用于其基类的属性。
文档注释似乎并没有说明太多意思,它是说给 BeanDefinition
做合并。借助IDEA,看一眼它的实现类:
这里面有一个我们一看就很兴奋: AutowiredAnnotationBeanPostProcessor
。
6.1.1 【重要】AutowiredAnnotationBeanPostProcessor
它的文档注释非常长,这里我们截取重要的部分:
BeanPostProcessor implementation that autowires annotated fields, setter methods and arbitrary config methods. Such members to be injected are detected through a Java 5 annotation: by default, Spring's @Autowired and @Value annotations. Also supports JSR-330's @Inject annotation, if available, as a direct alternative to Spring's own @Autowired. Only one constructor (at max) of any given bean class may declare this annotation with the 'required' parameter set to true, indicating the constructor to autowire when used as a Spring bean. If multiple non-required constructors declare the annotation, they will be considered as candidates for autowiring. The constructor with the greatest number of dependencies that can be satisfied by matching beans in the Spring container will be chosen. If none of the candidates can be satisfied, then a primary/default constructor (if present) will be used. If a class only declares a single constructor to begin with, it will always be used, even if not annotated. An annotated constructor does not have to be public. Fields are injected right after construction of a bean, before any config methods are invoked. Such a config field does not have to be public.
BeanPostProcessor
的实现,可自动连接带注解的字段,setter方法和任意config方法。通过Java 5注释检测要注入的此类成员:默认情况下,Spring的 @Autowired
和 @Value
注解。 还支持JSR-330的 @Inject
注解(如果可用),以替代Spring自己的 @Autowired
。 任何给定bean类的构造器(最大)只能使用 "required" 参数设置为true来声明此批注,指示在用作Spring bean时要自动装配的构造器。如果多个不需要的构造函数声明了注释,则它们将被视为自动装配的候选对象。将选择通过匹配Spring容器中的bean可以满足的依赖关系数量最多的构造函数。如果没有一个候选者满意,则将使用主/默认构造函数(如果存在)。如果一个类仅声明一个单一的构造函数开始,即使没有注释,也将始终使用它。带注解的构造函数不必是public的。 在构造任何bean之后,调用任何配置方法之前,立即注入字段。这样的配置字段不必是public的。 Config方法可以具有任意名称和任意数量的参数。这些参数中的每个参数都将与Spring容器中的匹配bean自动连接。 Bean属性设置器方法实际上只是这种常规config方法的特例。 Config方法不必是public的。
很明确,它就是完成自动注入的Bean后置处理器。它实现了 MergedBeanDefinitionPostProcessor
,那自然要实现接口中的方法:postProcessMergedBeanDefinition
:
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
这里面分两步,先获取注入的依赖,再进行对象检查。分步骤来看:
6.1.1.1 findAutowiringMetadata
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
// 首先从缓存中取,如果没有才创建
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
// 构建自动装配的信息
metadata = buildAutowiringMetadata(clazz);
// 放入缓存
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
这部分实现中使用了双检锁来保证线程安全,之后会构建自动装配的 metadata:
6.1.1.2 buildAutowiringMetadata
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
// 循环获取父类信息
do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
// 循环获取类上的属性,并判断是否有@Autowired等注入类注解
ReflectionUtils.doWithLocalFields(targetClass, field -> {
AnnotationAttributes ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
});
// 循环获取类上的方法,并判断是否有需要依赖的项
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static methods: " + method);
}
return;
}
if (method.getParameterCount() == 0) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return new InjectionMetadata(clazz, elements);
}
先看一眼这个 do-while 循环,这个 do-while 循环是用来一步一步往父类上爬的(可以看到这个循环体的最后一行是获取父类,判断条件是判断是否爬到了 Object
)。
循环体中,先是反射遍历当前类的属性,并判断上面是否有 @Autowired
等类型的注解。这部分注解的加载在这个方法中可以追溯到:
private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);
public AutowiredAnnotationBeanPostProcessor() {
this.autowiredAnnotationTypes.add(Autowired.class);
this.autowiredAnnotationTypes.add(Value.class);
try {
this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
if (ao.getAnnotations().length > 0) { // autowiring annotations have to be local
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ao, type);
if (attributes != null) {
return attributes;
}
}
}
return null;
}
可以发现这部分判断的几种注解: @Autowired
、@Value
、@Inject
。
之后又获取方法上的注解,也保存进去。最后获取父类,一层一层往上爬,直到循环跳出,方法结束。
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
下面要到 checkConfigMembers
方法了:
6.1.1.3 checkConfigMembers
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
for (InjectedElement element : this.injectedElements) {
Member member = element.getMember();
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
beanDefinition.registerExternallyManagedConfigMember(member);
checkedElements.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Registered injected element on class [" + this.targetClass.getName() + "]: " + element);
}
}
}
this.checkedElements = checkedElements;
}
这里面涉及到一个叫 Member
的概念:
Member is an interface that reflects identifying information about a single member (a field or a method) or a constructor.
反映有关单个成员(字段或方法)或构造函数的标识信息的接口。
看文档注释的意思,大概可以看出来它是表示类中的一个成员。
源码中的for循环,里面有两个很迷的方法。这两个方法都操作了 RootBeanDefinition
的一个属性:externallyManagedConfigMember
,而这部分除了这两个方法有调过,也没别的地方用了。这两个方法除了这个方法中使用过,别的地方也没用过。那看来这部分不会影响到大局,大可忽略。
至此,咱先对 AutowiredAnnotationBeanPostProcessor
这个后置处理器作一个了解,自动注入的原理会在后续慢慢看到。
再来看一个后置处理器,它是在注册BeanPostProcessor中的最后一步,显式声明的。
6.2 ApplicationListenerDetector
注意上面的截图,会发现 ApplicationListenerDetector
也实现了 MergedBeanDefinitionPostProcessor
。而且这个类在之前第11篇的3.3章节介绍过它,它的作用是收集监听器。它是 BeanPostProcessor
,但同时它也是 MergedBeanDefinitionPostProcessor
。那咱来看看它实现 MergedBeanDefinitionPostProcessor
后实现的方法:
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
this.singletonNames.put(beanName, beanDefinition.isSingleton());
}
可以发现非常简单,只是保存Bean是否为单实例Bean的信息。这个单实例Bean的机制在前面也提到过,只有单实例Bean才能注册到监听器列表中。
至此,registerBeanPostProcessors
方法执行完毕。
7. initMessageSource:初始化MessageSource
public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 检查是否已经存在了MessageSource组件,如果有,直接赋值
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isDebugEnabled()) {
logger.debug("Using MessageSource [" + this.messageSource + "]");
}
}
// 如果没有,创建一个,并注册到BeanFactory中
else {
// Use empty MessageSource to be able to accept getMessage calls.
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
"': using default [" + this.messageSource + "]");
}
}
}
这个组件我们在之前第7篇的IOC容器介绍(1.3.2章节)中说过,它是实现国际化的接口。
它默认创建的实现类是 DelegatingMessageSource
,它的文档注释:
Empty MessageSource
that delegates all calls to the parent MessageSource. If no parent is available, it simply won't resolve any message.
Used as placeholder by AbstractApplicationContext, if the context doesn't define its own MessageSource. Not intended for direct use in applications.
空的MessageSource,将所有调用委派给父MessageSource。如果没有父母可用,它将根本无法解决任何消息。
如果上下文未定义其自己的MessageSource,则AbstractApplicationContext用作占位符。不适用于直接在应用程序中使用。
其实,DelegatingMessageSource
扮演的角色更像是一种 “消息源解析的委派”(用户未指定时,IOC容器会默认使用 DelegatingMessageSource
)。它的功能比较简单:将字符串和参数数组格式化为一个国际化后的消息。
8. initApplicationEventMulticaster:初始化事件派发器
private ApplicationEventMulticaster applicationEventMulticaster;
public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
// 初始化当前ApplicationContext的事件广播器
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
// 8.1 ApplicationEventMulticaster
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}
源码中先判断IOC容器中是否有名称为 applicationEventMulticaster
的Bean,没有就默认注册一个 ApplicationEventMulticaster
。
8.1 ApplicationEventMulticaster
它的文档注释原文翻译:
Interface to be implemented by objects that can manage a number of ApplicationListener objects, and publish events to them.
由可以管理多个 ApplicationListener
对象并向其发布事件的对象实现的接口。
可以发现它就是一个事件发布器而已。它的核心方法-事件发布的源码如下:
@Override
public void multicastEvent(ApplicationEvent event) {
// 往下面的方法跳转
multicastEvent(event, resolveDefaultEventType(event));
}
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
// 执行监听器,继续往下跳转
invokeListener(listener, event);
}
}
}
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
ErrorHandler errorHandler = getErrorHandler();
if (errorHandler != null) {
try {
// 真正执行监听器的方法
doInvokeListener(listener, event);
}
catch (Throwable err) {
errorHandler.handleError(err);
}
}
else {
doInvokeListener(listener, event);
}
}
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
// ApplicationListener的方法
listener.onApplicationEvent(event);
}
catch (ClassCastException ex) {
String msg = ex.getMessage();
if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
// Possibly a lambda-defined listener which we could not resolve the generic event type for
// -> let's suppress the exception and just log a debug message.
Log logger = LogFactory.getLog(getClass());
if (logger.isTraceEnabled()) {
logger.trace("Non-matching event type for listener: " + listener, ex);
}
}
else {
throw ex;
}
}
}
可以发现它最终会执行到 ApplicationListener
的 onApplicationEvent
方法,思路比较简单。
9. onRefresh:子类扩展刷新
protected void onRefresh() throws BeansException {
// For subclasses: do nothing by default.
}
发现又是模板方法。这部分我们单独留到第16篇再展开描述,SpringBoot 在这里做了额外的操作。
10. registerListeners:注册监听器
protected void registerListeners() {
// Register statically specified listeners first.
// 把所有的IOC容器中以前缓存好的一组ApplicationListener取出来,添加到事件派发器中
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
// 拿到BeanFactory中定义的所有的ApplicationListener类型的组件全部取出,添加到事件派发器中
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
// 10.1 广播早期事件
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
public Collection<ApplicationListener<?>> getApplicationListeners() {
return this.applicationListeners;
}
监听器在IOC容器中早就注册好了,取出来后要放入事件广播器,以方便事件广播器广播事件。
在上面方法的最后一段,它广播了早期事件。
之前在最开始我们遇见过早期事件(refresh的第一步),下面咱要真正的说说这个早期事件了。
10.1 earlyEvent:早期事件
在 refresh
方法的 prepareRefresh
中,最后一步有这么一句:
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
// 这个集合的作用,是保存容器中的一些事件,以便在合适的时候利用事件广播器来广播这些事件
// 【配合registerListeners方法中的第三部分使用】
this.earlyApplicationEvents = new LinkedHashSet<>();
这里存储的事件会在这一步被触发。由此也知早期事件的发布时机:监听器被注册,但其余的单实例Bean还没有创建时。
实际上,通过Debug,发现默认情况下这里根本就没有早期事件:
由此也大概猜到这个早期事件的设计由来:留给开发者,在后置处理器和监听器都被创建好,其余的单实例Bean还没有创建时,提供一个预留的时机来处理一些额外的事情。
10.2 【扩展】SpringFramework中的观察者模式
实际上 ApplicationListener
与 ApplicationEvent
这样的事件派发机制就是观察者模式的体现。
事件派发器(广播器)、事件监听器(被通知者)、事件(ApplicationEvent
),其实这就是构成观察者模式的三大组件
广播器(
ApplicationEventMulticaster
):观察事件发生被通知者(
ApplicationListener
):接收广播器发送的广播,并做出相应的行为
11. finishBeanFactoryInitialization:初始化单实例Bean
源码分为好几部分,前面的部分都不算很关键,注释已标注在源码中,最后一句代码是核心关键点:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// 初始化ConversionService,这个ConversionService是用于类型转换的服务接口。
// 它的工作,是将配置文件/properties中的数据,进行类型转换,得到Spring真正想要的数据类型。
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));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
// 嵌入式值解析器EmbeddedValueResolver的组件注册,它负责解析占位符和表达式
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
// 尽早初始化LoadTimeWeaverAware类型的bean,以允许尽早注册其变换器。
// 这部分与LoadTimeWeaverAware有关部分,它实际上是与AspectJ有关
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
// 停用临时类加载器(单行注释解释的很清楚)
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
// 允许缓存所有bean定义元数据
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
// 【初始化】实例化所有非延迟加载的单例Bean
beanFactory.preInstantiateSingletons();
}
11.1 preInstantiateSingletons
它跳转到了 DefaultListableBeanFactory
的 preInstantiateSingletons
方法:
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
// 拿到了所有的Bean定义信息,这些信息已经在前面的步骤中都准备完毕了
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
// 这里面有一些Bean已经在之前的步骤中已经创建过了,这里只创建剩余的那些非延迟加载的单例Bean
for (String beanName : beanNames) {
// 合并父BeanFactory中同名的BeanDefinition,
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 这个Bean不是抽象Bean、是单例Bean、是非延迟加载的Bean
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 是否为工厂Bean(如果是工厂Bean,还需要实现FactoryBean接口)
if (isFactoryBean(beanName)) {
// 如果是工厂Bean:判断该工厂Bean是否需要被迫切加载,如果需要,则直接实例化该工厂Bean
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);
}
}
}
// 如果不是工厂Bean,直接调用getBean方法
else {
// 11.2 getBean
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
// 到这里,所有非延迟加载的单实例Bean都已经创建好。
// 如果有Bean实现了SmartInitializingSingleton接口,还会去回调afterSingletonsInstantiated方法
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();
}
}
}
}
上面的一系列判断后(判断逻辑已标注在源码上),如果不是工厂Bean,则会来到一个我们超级熟悉的方法: **getBean**
:
11.2 【核心】getBean
(源码超级长。。。)
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 11.2.1 此处是解决别名 -> BeanName的映射,getBean时可以传入bean的别名,此处可以根据别名找到BeanName
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 先尝试从之前实例化好的Bean中找有没有这个Bean,如果能找到,说明已经被实例化了,可以直接返回
// 11.2.2 getSingleton
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
// 11.2.3 上面get不到bean
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// 如果搜不到,但该Bean正在被创建,说明产生了循环引用且无法处理,只能抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
// 检查这个Bean对应的BeanDefinition在IOC容器中是否存在
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
// 如果检查不存在,看看父容器有没有(Web环境会存在父子容器现象)
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 {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
// 11.2.4 走到这个地方,证明Bean确实要被创建了,标记Bean被创建
// 该设计是防止多线程同时到这里,引发多次创建的问题
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
// 11.2.5 合并BeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 处理当前bean的bean依赖(@DependsOn注解的依赖)
// 在创建一个Bean之前,可能这个Bean需要依赖其他的Bean。
// 通过这个步骤,可以先递归的将这个Bean显式声明的需要的其他Bean先创建出来。
// 通过bean标签的depends-on属性或@DependsOn注解进行显式声明。
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
getBean(dep);
}
}
// Create bean instance.
// 作用域为singleton,单实例Bean,创建
if (mbd.isSingleton()) {
// 11.3,7 匿名内部类执行完成后的getSingleton调用
sharedInstance = getSingleton(beanName, () -> {
try {
// 11.4 createBean
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 作用域为prototype类型
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);
}
// 作用域既不是singleton,又不是prototype,那就按照实际情况来创建吧。
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;
}
}
// Check if required type matches the type of the actual bean instance.
// 检查所需的类型是否与实际bean实例的类型匹配,类型不匹配则抛出异常
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) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
这部分源码超级长!先大概浏览一下上面的源码和主干注释,下面咱们分段来看。
11.2.1 transformedBeanName:别名-BeanName的映射
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;
transformedBeanName
方法往下调:
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
public String canonicalName(String name) {
String canonicalName = name;
// Handle aliasing...
String resolvedName;
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}
发现它就是拿aliasMap去一个个的取,找别名映射的BeanName,找不到就返回原始名。
11.2.2 getSingleton:尝试获取单实例Bean(解决循环依赖)
// Eagerly check singleton cache for manually registered singletons.
// 先尝试从之前实例化好的Bean中找有没有这个Bean,如果能找到,说明已经被实例化了,可以直接返回
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
可以发现这段代码是在处理重复实例化的。IOC容器会对单实例Bean单独存储,这个地方就是从IOC容器中找是否已经被实例化。由于这部分源码复杂度过高,咱们在下一篇咱专门研究IOC容器如何解决循环依赖的。
11.2.3 创建前的检查
//上面get不到bean
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// 如果搜不到,但该Bean正在被创建,说明产生了循环引用且无法处理,只能抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
// 检查这个Bean对应的BeanDefinition在IOC容器中是否存在
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
// 如果检查不存在,看看父容器有没有(Web环境会存在父子容器现象)
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 {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
这里面有一个检查循环依赖的方法: isPrototypeCurrentlyInCreation
:
// 返回指定的原型bean是否当前正在创建(在当前线程内)
protected boolean isPrototypeCurrentlyInCreation(String beanName) {
Object curVal = this.prototypesCurrentlyInCreation.get();
return (curVal != null &&
(curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName))));
}
它这个方法是创建原型Bean时会校验的。如果当前线程中在创建一个 scope=prototype 的Bean,并且当前要创建的Bean跟这个线程中创建的Bean的name一致,则会认为出现了多实例Bean的循环依赖,会引发异常。
11.2.4 标记准备创建的Bean
// 走到这个地方,证明Bean确实要被创建了,标记Bean被创建
// 该设计是防止多线程同时到这里,引发多次创建的问题
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
这里的标记过程:
protected void markBeanAsCreated(String beanName) {
if (!this.alreadyCreated.contains(beanName)) {
synchronized (this.mergedBeanDefinitions) {
if (!this.alreadyCreated.contains(beanName)) {
// Let the bean definition get re-merged now that we're actually creating
// the bean... just in case some of its metadata changed in the meantime.
clearMergedBeanDefinition(beanName);
this.alreadyCreated.add(beanName);
}
}
}
}
最后一句:this.alreadyCreated.add(beanName);
,已经足够理解了。IOC容器会把所有创建过的Bean的name都存起来。
11.2.5 合并BeanDefinition,处理显式依赖
try {
// 合并BeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 处理当前bean的bean依赖(@DependsOn注解的依赖)
// 在创建一个Bean之前,可能这个Bean需要依赖其他的Bean。
// 通过这个步骤,可以先递归的将这个Bean显式声明的需要的其他Bean先创建出来。
// 通过bean标签的depends-on属性或@DependsOn注解进行显式声明。
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
getBean(dep);
}
}
这部分会解析 @DependsOn
注解标注声明的Bean,并预先的构建它,被依赖的Bean也是通过 getBean
方法来创建,思路一致,不再赘述。
11.2.6 准备创建Bean
// Create bean instance.
// 作用域为singleton,单实例Bean,创建
if (mbd.isSingleton()) {
// 匿名内部类执行完成后的getSingleton调用
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
在try块中,要真正的创建Bean了。注意 createBean
方法是通过 getSingleton
方法传入匿名内部类,调用的 createBean
方法。先来看 getSingleton
方法:
11.3 getSingleton
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
// 先试着从已经加载好的单实例Bean缓存区中获取是否有当前BeanName的Bean,显然没有
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 11.3.1 标记当前bean
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 11.4 创建Bean
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 将这个创建好的Bean放到单实例Bean缓存区中
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
注意这里做了很重要的一步:如果当前准备创建的Bean还没有在IOC容器中,就标记一下它:
11.3.1 beforeSingletonCreation
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
注意if的判断结构中,有一个 this.singletonsCurrentlyInCreation.add(beanName)
,它的作用就是把当前准备创建的beanName放入 singletonsCurrentlyInCreation
中。它的作用是解决循环依赖,咱下一篇专门来解释循环依赖的处理。
11.4 createBean
注意跳转到的类:**AbstractAutowireCapableBeanFactory**
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
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.
// 先拿到这个Bean的定义信息,获取Bean的类型
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
// 方法重写的准备工作
// 利用反射,对该Bean对应类及其父类的方法定义进行获取和加载,确保能够正确实例化出该对象
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.
// 11.5 给BeanPostProcessors一个机会,来返回代理而不是目标bean实例
// 这个步骤是确保可以创建的是被增强的代理对象而不是原始对象(AOP)
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
//如果动态代理创建完毕,将直接返回该Bean
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
// 如果不需要创建动态代理对象,则执行下面的doCreateBean
try {
// 11.6 doCreateBean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException ex) {
// A previously detected exception with proper bean creation context already...
throw ex;
}
catch (ImplicitlyAppearedSingletonException ex) {
// An IllegalStateException to be communicated up to DefaultSingletonBeanRegistry...
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
这段源码中重要的部分已经标注了注释,这里面两个重要的部分:AOP的入口,真正创建Bean的入口。
11.5 resolveBeforeInstantiation:AOP
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
//
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
**InstantiationAwareBeanPostProcessor**
是 BeanPostProcessor
的子接口,它的文档注释:
Subinterface of BeanPostProcessor that adds a before-instantiation callback, and a callback after instantiation but before explicit properties are set or autowiring occurs. Typically used to suppress default instantiation for specific target beans, for example to create proxies with special TargetSources (pooling targets, lazily initializing targets, etc), or to implement additional injection strategies such as field injection. NOTE: This interface is a special purpose interface, mainly for internal use within the framework. It is recommended to implement the plain BeanPostProcessor interface as far as possible, or to derive from InstantiationAwareBeanPostProcessorAdapter in order to be shielded from extensions to this interface.
BeanPostProcessor
的子接口,它添加实例化之前的回调,以及在实例化之后但在设置显式属性或发生自动装配之前的回调。
通常用于抑制特定目标Bean的默认实例化,例如创建具有特殊 TargetSource
的代理(池目标,延迟初始化目标等),或实现其他注入策略,例如字段注入。
注意:此接口是专用接口,主要供框架内部使用。建议尽可能实现普通的 BeanPostProcessor
接口,或从 InstantiationAwareBeanPostProcessorAdapter
派生,以免对该接口进行扩展。
划重点:抑制特定目标Bean的默认实例化。也就是说这个接口对应的部分是真正的AOP创建代理对象的部分!
关于AOP的部分,后面有专门的篇章来分析AOP的原理,此处先跳过。
11.6 doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
// 实例化Bean,并创建一个BeanWrapper,对Bean进行包装
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 确保已经实例化的Bean中没有当前要创建的bean,而且不是工厂Bean,才可以开始创建
if (instanceWrapper == null) {
// 11.6.1 createBeanInstance
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
// MergedBeanDefinitionPostProcessor可以修改Bean的定义
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 这个方法只允许MergedBeanDefinitionPostProcessor执行
// MergedBeanDefinitionPostProcessor也是BeanPostProcessor的子接口,之前介绍过了
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 缓存单例对象,以便能够解析循环引用,甚至在生命周期接口(如BeanFactoryAware)触发时也是如此
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
// 给Bean赋值
Object exposedObject = bean;
try {
// 11.6.2 populateBean:属性赋值和自动注入
populateBean(beanName, mbd, instanceWrapper);
// 11.6.3 initializeBean:初始化Bean
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
// 又获取那个单例Bean,前面已经创建好了,但还没有缓存到IOC容器中,所以这里仍然返回null,故这部分是会跳过的
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
// 注册Bean的销毁方法,销毁方法在IOC容器关闭后再销毁
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
源码中发现Bean的创建需要几个重要的步骤:
createBeanInstance:创建Bean对象
addSingletonFactory:Bean放入缓存(涉及到循环依赖,下一篇详细介绍)
populateBean:属性复制和自动注入
initializeBean:初始化后处理
11.6.1 【真正实例化】createBeanInstance
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
// 解析Bean的类型
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
// 11.6.1.1 判断是否有用于创建bean实例的特殊的回调方法
// 如果存在,会使用特殊的callback回调方法,通过这个callback创建bean
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 11.6.1.2 判断是否有工厂方法,如果存在,会尝试调用该Bean定义信息中的工厂方法来获取实例
// 如果使用注解方式注册的Bean,会跳到该Bean的注册方法中(配置类中定义的那些Bean)
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
// 一个类可能有多个构造器,所以Spring得根据参数个数、类型确定需要调用的构造器
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
// 在使用构造器创建实例后,会将解析过后确定下来的构造器或工厂方法保存在缓存中,避免再次创建相同bean时再次解析,导致循环依赖
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
// 构造器注入创建Bean
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 普通创建
return instantiateBean(beanName, mbd);
}
}
// Need to determine the constructor...
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
这里面的几个重要环节简单总结:
11.6.1.1 getInstanceSupplier:特殊的callback回调方法
这两个方法来自 AbstractBeanDefinition
:
public void setInstanceSupplier(@Nullable Supplier<?> instanceSupplier) {
this.instanceSupplier = instanceSupplier;
}
@Nullable
public Supplier<?> getInstanceSupplier() {
return this.instanceSupplier;
}
它只是简单地get和set而已,那它这个 Supplier
又是从哪里来的呢?借助IDEA,发现在 GenericApplicationContext
中有一个调用:
public <T> void registerBean(@Nullable String beanName, Class<T> beanClass,
@Nullable Supplier<T> supplier, BeanDefinitionCustomizer... customizers) {
ClassDerivedBeanDefinition beanDefinition = new ClassDerivedBeanDefinition(beanClass);
if (supplier != null) {
beanDefinition.setInstanceSupplier(supplier);
}
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(beanDefinition);
}
String nameToUse = (beanName != null ? beanName : beanClass.getName());
registerBeanDefinition(nameToUse, beanDefinition);
}
这个方法我们还是比较熟悉的,它用来向 BeanFactory
中注册 Bean 的定义信息。这个方法又是从哪里调用的呢?继续借助IDEA查看:
发现在 GenericApplicationContext
中只有这一个地方有传入 supplier,其余的地方都是null。再索引这个方法的调用位置,发现跟上面图中的 DefaultControllerSpec
位置差不多了,都在这个类中。而这个类所在包是 org.springframework.test
,是测试包中,我们不作关心。
那到这里来看,这个 Supplier
通常就是null了。
11.6.1.2 instantiateUsingFactoryMethod:工厂方法
这个工厂方法的由来,需要我们回到整个 refresh
方法的第5步:invokeBeanFactoryPostProcessors
。还记得当时在处理 BeanFactory
时回调了一组 BeanDefinitionRegistryPostProcessor
吗?它执行了一个很关键的后置处理器:ConfigurationClassPostProcessor
。不太记得的小伙伴请先翻回第12篇5.2章节回顾一下这部分,重要的环节是5.2.4章节。
在5.2.4章节中介绍了 @Bean
注解标注的方法的解析过程,这里面就有一个工厂方法的设置。那回到 doCreateBean
中,这里的 instantiateUsingFactoryMethod
方法就是对这种被 @Bean
注解标注的Bean进行创建。这个方法比较简单:
protected BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}
从方法名就可以很容易看出它是借助一个构造器处理器,来执行这个工厂方法中定义的Bean。这个方法的内容实在是太长了(220行+),我把关键的部分标注上注释,小伙伴们大概看一下整体思路就可以了:
public BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
// 构造BeanWrapper
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Object factoryBean;
Class<?> factoryClass;
boolean isStatic;
// 获取工厂方法名称
String factoryBeanName = mbd.getFactoryBeanName();
if (factoryBeanName != null) {
if (factoryBeanName.equals(beanName)) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"factory-bean reference points back to the same bean definition");
}
// 如果工厂方法不为空,则获取工厂实例,并标记该工厂方法不是静态方法
factoryBean = this.beanFactory.getBean(factoryBeanName);
if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
throw new ImplicitlyAppearedSingletonException();
}
factoryClass = factoryBean.getClass();
isStatic = false;
}
else {
// It's a static factory method on the bean class.
// 如果获取不到工厂方法名,则这应该是一个静态工厂,需要提供完整的工厂全限定类名,否则会抛出异常
if (!mbd.hasBeanClass()) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"bean definition declares neither a bean class nor a factory-bean reference");
}
factoryBean = null;
factoryClass = mbd.getBeanClass();
isStatic = true;
}
Method factoryMethodToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
// 这个explicitArgs是从这个方法的参数中传过来的,它是从getBean方法中传过来的
// 默认情况下getBean只有BeanName(AbstractBeanFactory的getBean(String name)方法),故这里为null
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached factory method...
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve, true);
}
}
// 上面的东西统统没有,进入下面的结构体中
if (factoryMethodToUse == null || argsToUse == null) {
// Need to determine the factory method...
// Try all methods with this name to see if they match the given arguments.
factoryClass = ClassUtils.getUserClass(factoryClass);
// 获取配置类中所有的方法(包括父类),称为候选方法
Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
List<Method> candidateList = new ArrayList<>();
for (Method candidate : rawCandidates) {
if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
candidateList.add(candidate);
}
}
// 因为@Bean只对当前要创建的Bean标注了一次,所以这里candidateList的大小必为1
if (candidateList.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Method uniqueCandidate = candidateList.get(0);
if (uniqueCandidate.getParameterCount() == 0) {
mbd.factoryMethodToIntrospect = uniqueCandidate;
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
// 按照构造方法参数的数量降序排序
Method[] candidates = candidateList.toArray(new Method[0]);
AutowireUtils.sortFactoryMethods(candidates);
ConstructorArgumentValues resolvedValues = null;
boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Method> ambiguousFactoryMethods = null;
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
// We don't have arguments passed in programmatically, so we need to resolve the
// arguments specified in the constructor arguments held in the bean definition.
// 没有以编程方式在getBean方法中传递参数,因此需要解析在bean定义中保存的构造函数参数中指定的参数
if (mbd.hasConstructorArgumentValues()) {
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
else {
minNrOfArgs = 0;
}
}
LinkedList<UnsatisfiedDependencyException> causes = null;
for (Method candidate : candidates) {
// 解析被@Bean标注的方法的参数
Class<?>[] paramTypes = candidate.getParameterTypes();
if (paramTypes.length >= minNrOfArgs) {
ArgumentsHolder argsHolder;
if (explicitArgs != null) {
// Explicit arguments given -> arguments length must match exactly.
if (paramTypes.length != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}
// getBean中没有传入参数,这里需要解析构造方法中的参数
else {
// Resolved constructor arguments: type conversion and/or autowiring necessary.
// 解决的构造函数参数:类型转换、自动装配是必需的
try {
String[] paramNames = null;
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
// 在已经解析的构造函数参数值的情况下,创建一个参数持有者对象
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,
paramTypes, paramNames, candidate, autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Ignoring factory method [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next overloaded factory method.
if (causes == null) {
causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
}
// 【扩展】解析构造方法的参数时使用严格模式还是宽松模式
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this factory method if it represents the closest match.
if (typeDiffWeight < minTypeDiffWeight) {
factoryMethodToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousFactoryMethods = null;
}
// Find out about ambiguity: In case of the same type difference weight
// for methods with the same number of parameters, collect such candidates
// and eventually raise an ambiguity exception.
// However, only perform that check in non-lenient constructor resolution mode,
// and explicitly ignore overridden methods (with the same parameter signature).
else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
!mbd.isLenientConstructorResolution() &&
paramTypes.length == factoryMethodToUse.getParameterCount() &&
!Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
if (ambiguousFactoryMethods == null) {
ambiguousFactoryMethods = new LinkedHashSet<>();
ambiguousFactoryMethods.add(factoryMethodToUse);
}
ambiguousFactoryMethods.add(candidate);
}
}
}
// 如果发现没有可执行的工厂方法,进行一系列检查后可能会抛出异常
if (factoryMethodToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
List<String> argTypes = new ArrayList<>(minNrOfArgs);
if (explicitArgs != null) {
for (Object arg : explicitArgs) {
argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
}
}
else if (resolvedValues != null) {
Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
valueHolders.addAll(resolvedValues.getGenericArgumentValues());
for (ValueHolder value : valueHolders) {
String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) :
(value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null"));
argTypes.add(argType);
}
}
String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"No matching factory method found: " +
(mbd.getFactoryBeanName() != null ?
"factory bean '" + mbd.getFactoryBeanName() + "'; " : "") +
"factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. " +
"Check that a method with the specified name " +
(minNrOfArgs > 0 ? "and arguments " : "") +
"exists and that it is " +
(isStatic ? "static" : "non-static") + ".");
}
else if (void.class == factoryMethodToUse.getReturnType()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Invalid factory method '" + mbd.getFactoryMethodName() +
"': needs to have a non-void return type!");
}
else if (ambiguousFactoryMethods != null) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous factory method matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousFactoryMethods);
}
if (explicitArgs == null && argsHolderToUse != null) {
mbd.factoryMethodToIntrospect = factoryMethodToUse;
argsHolderToUse.storeCache(mbd, factoryMethodToUse);
}
}
Assert.state(argsToUse != null, "Unresolved factory method arguments");
// 实例化Bean,包装BeanWraper
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
return bw;
}
源码好长,但总结下来就干了一件事:确定工厂方法 + 实例化、包装 BeanWrapper
。
源码中提到了一个比较有意思的概念:解析构造方法参数的严格模式/宽松模式。
11.6.1.3 【扩展】严格模式/宽松模式
咱们单独把这一段摘出来:
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this factory method if it represents the closest match.
if (typeDiffWeight < minTypeDiffWeight) {
factoryMethodToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousFactoryMethods = null;
}
默认情况下 lenientConstructorResolution
的值为true, 为严格模式。下面先看一眼这两种模式下的计算规则:
// 严格模式
public int getTypeDifferenceWeight(Class<?>[] paramTypes) {
// If valid arguments found, determine type difference weight.
// Try type difference weight on both the converted arguments and
// the raw arguments. If the raw weight is better, use it.
// Decrease raw weight by 1024 to prefer it over equal converted weight.
// 如果找到有效的参数,请确定类型差异权重。尝试对转换后的参数和原始参数都使用类型差异权重。
// 如果原始权重更好,请使用它。将原始权重减少1024,以使其优于相等的转换权重。
// 先拿转换之后的参数对比
int typeDiffWeight = MethodInvoker.getTypeDifferenceWeight(paramTypes, this.arguments);
// 再拿原始参数对比
int rawTypeDiffWeight = MethodInvoker.getTypeDifferenceWeight(paramTypes, this.rawArguments) - 1024;
// 由值确定选哪一个,值越小越接近参数声明类型
return (rawTypeDiffWeight < typeDiffWeight ? rawTypeDiffWeight : typeDiffWeight);
}
// 宽松模式
public int getAssignabilityWeight(Class<?>[] paramTypes) {
for (int i = 0; i < paramTypes.length; i++) {
if (!ClassUtils.isAssignableValue(paramTypes[i], this.arguments[i])) {
return Integer.MAX_VALUE;
}
}
for (int i = 0; i < paramTypes.length; i++) {
if (!ClassUtils.isAssignableValue(paramTypes[i], this.rawArguments[i])) {
return Integer.MAX_VALUE - 512;
}
}
return Integer.MAX_VALUE - 1024;
}
严格模式下,必须要求参数类型完全一致
这个方法的实现涉及到算法,不作细致研究,小伙伴们了解即可,感兴趣的小伙伴可以Debug运行看一下机制。
宽松模式,只要参数是声明类型或子类型即可
如果使用宽松模式,会出现一个问题:如果构造方法中传入两个接口,而这两个接口分别有两个实现类,此时IOC容器会觉得这两个对象都可以放到这两个参数中,造成权重一致,出现构造方法歧义。
11.6.2 populateBean:属性赋值和自动注入
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
boolean continueWithPropertyPopulation = true;
// 执行所有InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
// 11.6.2.1 又拿了那些InstantiationAwareBeanPostProcessor,不过这次执行的方法不同:postProcessPropertyValues
// 这些InstantiationAwareBeanPostProcessor其中有一个能实现 @Autowired、@Value 等注入
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
// 11.6.2. 使用setter方式,给Bean赋值和自动注入
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
在源码中,通过那一组 InstantiationAwareBeanPostProcessor
就可以实现 @Autowired
、@Value
等自动注入。
如果是通过 setter
的方式进行自动注入,会走最后的一个if结构,调用 applyPropertyValues
方法。
下面分别分析这两种注入机制。
11.6.2.1 @Autowired 的自动注入
咱在之前13篇的6.1.1章节中介绍过一个后置处理器:**AutowiredAnnotationBeanPostProcessor**
。咱之前也说过,它就是实现 @Autowired
的自动注入。
它的类定义:
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware
public abstract class InstantiationAwareBeanPostProcessorAdapter implements SmartInstantiationAwareBeanPostProcessor
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor
它集成了 InstantiationAwareBeanPostProcessorAdapter
,而 InstantiationAwareBeanPostProcessorAdapter
又实现了 SmartInstantiationAwareBeanPostProcessor
接口,SmartInstantiationAwareBeanPostProcessor
接口最终继承了 InstantiationAwareBeanPostProcessor
接口。那上面看到的核心回调方法就是 postProcessProperties
:
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
第一句咱们之前看过了,知道是构建自动注入的元数据,下面的 inject
方法是真正的自动注入。
11.6.2.2 [Autowired] inject
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
if (logger.isTraceEnabled()) {
logger.trace("Processing injected element of bean '" + beanName + "': " + element);
}
element.inject(target, beanName, pvs);
}
}
}
这里面最底下调了 element.inject
方法。借助IDEA,在打开这个方法时发现这个方法有两个子类重写了这个方法,分别是 AutowiredFieldElement
和 AutowiredMethodElement
。很明显它们是给属性注入和方法注入的。我们以属性注入为例分析(关键源码的注释已标注在源码中):
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
// 如果这个值在前面的注入中有缓存过,直接取缓存
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
// 没有缓存,要在下面的try块中利用BeanFactory处理依赖关系
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
// 【关联创建】value应该被找出 / 创建出
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
// 处理完成后要对这个属性进行缓存
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
// 把这个依赖的Bean添加到BeanFactory的依赖关系映射上缓存起来
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
// 如果找到 / 创建好了value,就给它注入
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
上面的检查完成后,在try块中的核心方法可以用来关联创建被依赖的Bean:beanFactory.resolveDependency
。
11.6.2.3 [Autowired] beanFactory.resolveDependency
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
上面的一些if-else结构判断都是检验被标注 @Autowired
注解的属性类型,显然上面的一些类型一般都不用,直接来看下面的最后一个else结构:它调用 doResolveDependency
方法来解决依赖:
11.6.2.4 [Autowired] doResolveDependency
(核心步骤的注释已标注在源码中)
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
// 该方法默认是调用DependencyDescriptor的方法,没有子类,默认实现是返回null
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
Class<?> type = descriptor.getDependencyType();
// 处理@Value注解
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
// 处理数组、集合、Map等
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
// 从现有的已经创建好的Bean实例中找可以匹配到该自动注入的字段上的Bean
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
// 如果找到了,超过1个,会决定使用哪个Bean更合适,如果真的分辨不出来,则会抛出异常
if (matchingBeans.size() > 1) {
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// We have exactly one match.
// 匹配不到,要走下面的创建流程
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
// 关联创建
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
注意看源码中靠下部分的 descriptor.resolveCandidate(autowiredBeanName, type, this);
,在一开始什么Bean都匹配不到的情况下,Debug发现会来到这里,而这个方法的实现:
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
throws BeansException {
return beanFactory.getBean(beanName);
}
它回到getBean中,开始关联创建。
创建好后,回到 inject
方法:
// 如果找到 / 创建好了value,就给它注入
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
利用反射注入属性值。至此,可以发现 @Autowired
的自动注入和关联创建流程。
11.6.2.5 [setter] applyPropertyValues
使用setter方法,前面的一大段都不走了,直接来到最后的 applyPropertyValues
方法。
进入到 applyPropertyValues
方法中(不太关键的部分注释已标注在源码中):
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
// 没有任何要属性赋值/自动注入,直接返回
if (pvs.isEmpty()) {
return;
}
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
MutablePropertyValues mpvs = null;
// 需要转换的属性
List<PropertyValue> original;
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();
}
else {
original = Arrays.asList(pvs.getPropertyValues());
}
// 类型转换器是可以自定义的
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
// BeanDefinitionValueResolver是真正实现属性赋值和自动注入的
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original) {
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
// 11.6.2.6 【核心】解析、注入值
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
// 将已经转换过的值放入缓存,避免重复解析降低效率
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
// 标记已经转换完毕
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
这里面的核心方法:**valueResolver.resolveValueIfNecessary**
11.6.2.6 [setter] resolveValueIfNecessary
public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
// We must check each value to see whether it requires a runtime reference
// to another bean to be resolved.
// 11.6.2.7 如果依赖了另外一个Bean时,进入下面的分支
if (value instanceof RuntimeBeanReference) {
RuntimeBeanReference ref = (RuntimeBeanReference) value;
return resolveReference(argName, ref);
}
// 如果根据另一个Bean的name进行依赖,进入下面的分支
else if (value instanceof RuntimeBeanNameReference) {
String refName = ((RuntimeBeanNameReference) value).getBeanName();
refName = String.valueOf(doEvaluate(refName));
if (!this.beanFactory.containsBean(refName)) {
throw new BeanDefinitionStoreException(
"Invalid bean name '" + refName + "' in bean reference for " + argName);
}
return refName;
}
// 解析BeanDefinitionHolder
else if (value instanceof BeanDefinitionHolder) {
// Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
}
// 解析纯BeanDefinition
else if (value instanceof BeanDefinition) {
// Resolve plain BeanDefinition, without contained name: use dummy name.
BeanDefinition bd = (BeanDefinition) value;
String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
ObjectUtils.getIdentityHexString(bd);
return resolveInnerBean(argName, innerBeanName, bd);
}
// 解析数组
else if (value instanceof ManagedArray) {
// May need to resolve contained runtime references.
ManagedArray array = (ManagedArray) value;
Class<?> elementType = array.resolvedElementType;
if (elementType == null) {
String elementTypeName = array.getElementTypeName();
if (StringUtils.hasText(elementTypeName)) {
try {
elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
array.resolvedElementType = elementType;
}
catch (Throwable ex) {
// Improve the message by showing the context.
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Error resolving array type for " + argName, ex);
}
}
else {
elementType = Object.class;
}
}
return resolveManagedArray(argName, (List<?>) value, elementType);
}
// 11.6.2.8 解析List
else if (value instanceof ManagedList) {
// May need to resolve contained runtime references.
return resolveManagedList(argName, (List<?>) value);
}
// 解析Set
else if (value instanceof ManagedSet) {
// May need to resolve contained runtime references.
return resolveManagedSet(argName, (Set<?>) value);
}
// 解析Map
else if (value instanceof ManagedMap) {
// May need to resolve contained runtime references.
return resolveManagedMap(argName, (Map<?, ?>) value);
}
// 解析Properties
else if (value instanceof ManagedProperties) {
Properties original = (Properties) value;
Properties copy = new Properties();
original.forEach((propKey, propValue) -> {
if (propKey instanceof TypedStringValue) {
propKey = evaluate((TypedStringValue) propKey);
}
if (propValue instanceof TypedStringValue) {
propValue = evaluate((TypedStringValue) propValue);
}
if (propKey == null || propValue == null) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Error converting Properties key/value pair for " + argName + ": resolved to null");
}
copy.put(propKey, propValue);
});
return copy;
}
// 解析String
else if (value instanceof TypedStringValue) {
// Convert value to target type here.
TypedStringValue typedStringValue = (TypedStringValue) value;
Object valueObject = evaluate(typedStringValue);
try {
Class<?> resolvedTargetType = resolveTargetType(typedStringValue);
if (resolvedTargetType != null) {
return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
}
else {
return valueObject;
}
}
catch (Throwable ex) {
// Improve the message by showing the context.
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Error converting typed String value for " + argName, ex);
}
}
else if (value instanceof NullBean) {
return null;
}
else {
return evaluate(value);
}
}
解析上面几个标号的分支,了解属性赋值和自动注入的核心
11.6.2.7 [setter] RuntimeBeanReference
if (value instanceof RuntimeBeanReference) {
RuntimeBeanReference ref = (RuntimeBeanReference) value;
return resolveReference(argName, ref);
}
这部分跳转到了 resolveReference
方法:
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
try {
Object bean;
// 获取BeanName
String refName = ref.getBeanName();
refName = String.valueOf(doEvaluate(refName));
// 如果Bean在父容器,则去父容器取
if (ref.isToParent()) {
if (this.beanFactory.getParentBeanFactory() == null) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Can't resolve reference to bean '" + refName +
"' in parent factory: no parent factory available");
}
bean = this.beanFactory.getParentBeanFactory().getBean(refName);
}
else {
// 在本容器,调用getBean
bean = this.beanFactory.getBean(refName);
this.beanFactory.registerDependentBean(refName, this.beanName);
}
if (bean instanceof NullBean) {
bean = null;
}
return bean;
}
catch (BeansException ex) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
}
}
发现这里面的核心还是getBean方法!开始触发关联创建Bean。
11.6.2.8 [setter] 解析List
else if (value instanceof ManagedList) {
// May need to resolve contained runtime references.
return resolveManagedList(argName, (List<?>) value);
}
跳转到 resolveManagedList
方法:
private List<?> resolveManagedList(Object argName, List<?> ml) {
List<Object> resolved = new ArrayList<>(ml.size());
for (int i = 0; i < ml.size(); i++) {
resolved.add(resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));
}
return resolved;
}
这里面直接把 List
集合塞入属性中即可。
至此,属性赋值和自动注入得以体现,至于这里面如何解决循环依赖,下一篇详细描述。
11.6.3 initializeBean:初始化Bean
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 11.6.3.1 将那些实现xxxAware接口的类,注入一些属性(beanName、ClassLoader、BeanFactory)
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 11.6.3.2 后置处理器在做初始化之前的处理
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 11.6.3.3 初始化Bean,执行@PostConstruct,InitializingBean接口的方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 后置处理器在做初始化之后的处理
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
11.6.3.1 invokeAwareMethods:执行注入的功能
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
可以发现这里面是对 BeanName 的注入,BeanClassLoader
的注入,以及 BeanFactory
的注入,实现很简单,不再展开。
11.6.3.2 applyBeanPostProcessorsBeforeInitialization:执行后置处理器
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;
}
发现这里是真正的执行 BeanPostProcessor
的方法了,调用逻辑也很简单,不再展开。
11.6.3.3 invokeInitMethods:执行初始化Bean的操作
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 不是InitializiingBean,而且也没声明afterPropertiesSet方法,则不执行下面的逻辑
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
可以发现这里只有执行了 InitializiingBean
接口的 afterPropertiesSet
方法,没有找到 @PostConstruct
标注的方法。根据之前的分析,知道 @PostConstruct
标注的方法会先执行。那上面的源码中,执行 InitializingBean
的方法之前只有执行 BeanPostProcessor
了,那可以大概猜测是一个 BeanPostProcessor
执行了 @PostConstruct
方法。
通过给一个自定义的组件声明测试方法,并标注 PostConstruct
,发现它的调用栈里有一个 InitDestroyAnnotationBeanPostProcessor
,它的执行方法 postProcessBeforeInitilization
方法如下:
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
try {
metadata.invokeInitMethods(bean, beanName);
}
catch (InvocationTargetException ex) {
throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
}
return bean;
}
可以发现调用了 metadata.invokeInitMethods
方法执行了 @PostConstruct
标注的方法。
至此,可以发现初始化Bean的逻辑也调用完成,整个 doCreateBean
方法执行完毕。
回到 getBean
方法中:
if (mbd.isSingleton()) {
// 11.7 匿名内部类执行完成后的getSingleton调用
sharedInstance = getSingleton(beanName, () -> {
try {
// 11.3 createBean
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
在 createBean
执行完后,回到了匿名内部类的 getSingleton
方法:
11.7 匿名内部类执行完成后的getSingleton调用
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// ......
try {
// createBean方法在getObject中
singletonObject = singletonFactory.getObject();
newSingleton = true;
} // catch ......
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 将这个创建好的Bean放到IOC容器的单实例Bean缓存区中
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
调用完成后,finally 块中还有一步操作:
protected void afterSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
在if条件中,它要把当前Bean的name从 singletonsCurrentlyInCreation
(正在被创建的Bean)中清除。
最终,将这个Bean添加到 singletonObjects
(一级缓存)中,createBean
方法彻底完成。
11.8 最后的工作
回到 preInstantiateSingletons
中。
// Trigger post-initialization callback for all applicable beans...
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();
}
}
}
它又回调了一组类型为 SmartInitializingSingleton
的组件,来回调它们的 afterSingletonsInstantiated
方法。
11.8.1 SmartInitializingSingleton
它的文档注释原文翻译:
Callback interface triggered at the end of the singleton pre-instantiation phase during BeanFactory bootstrap. This interface can be implemented by singleton beans in order to perform some initialization after the regular singleton instantiation algorithm, avoiding side effects with accidental early initialization (e.g. from ListableBeanFactory.getBeansOfType calls). In that sense, it is an alternative to InitializingBean which gets triggered right at the end of a bean's local construction phase. This callback variant is somewhat similar to org.springframework.context.event.ContextRefreshedEvent but doesn't require an implementation of org.springframework.context.ApplicationListener, with no need to filter context references across a context hierarchy etc. It also implies a more minimal dependency on just the beans package and is being honored by standalone ListableBeanFactory implementations, not just in an org.springframework.context.ApplicationContext environment. NOTE: If you intend to start/manage asynchronous tasks, preferably implement org.springframework.context.Lifecycle instead which offers a richer model for runtime management and allows for phased startup/shutdown.
在 BeanFactory
引导期间的单实例bean的初始化阶段结束时触发的回调接口。该接口可以由单例bean实现,以便在常规的单例实例化算法之后执行一些初始化,避免意外的早期初始化带来的副作用(例如,来自 ListableBeanFactory.getBeansOfType
调用)。从这个意义上讲,它是 InitializingBean
的替代方法,后者在bean的本地构造阶段结束时立即触发。 这个回调变体有点类似于 org.springframework.context.event.ContextRefreshedEvent
,但是不需要 org.springframework.context.ApplicationListener
的实现,不需要在整个上下文层次结构中过滤上下文引用。这也意味着更多对bean包的依赖性最小,并且由独立的ListableBeanFactory实现兑现,而不仅仅是在 ApplicationContext
环境中。 注意:如果要启动/管理异步任务,则最好实现 org.springframework.context.Lifecycle
,它为运行时管理提供了更丰富的模型,并允许分阶段启动/关闭。
从文档注释来看,它是 InitializingBean
的替代方案,但通过上面的代码也了解,它的执行时机是:所有单实例Bean都创建完毕。小伙伴们大概对这个地方有个印象即可,后续的源码分析中可能会遇到,我会再往回提的。
最后更新于