Spring启动流程
创建上下文对象
//创建上下文对象,下边是源码流程
AnnotationConfigApplicationContext annotationConfigApplicationContext =new AnnotationConfigApplicationContext(ImportConfig.class);
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
/**
* 调用父类构造方法,获取Bean工厂,默认DefaultListableBeanFactory
* 初始化内置的工厂后置处理器,可以用于解析常用注解
* 初始化环境信息,类加载器,初始化配置文件解析器
*
* 五个内置BeanDefinition
* BeanFactory.BeanDefinitionMap=>
* 0 = "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"
* 这个BeanDefinition是ConfigurationClassPostProcessor生成的,显示的是key值,value为BeanDefinition。
* ConfigurationClassPostProcessor的作用在下边补充
* 1 = "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"
* 2 = "org.springframework.context.annotation.internalCommonAnnotationProcessor"
* 3 = "org.springframework.context.event.internalEventListenerProcessor"
* 4 = "org.springframework.context.event.internalEventListenerFactory"
*/
this();
//register(componentClasses) 注册ImportConfig的BeanDefinition
// BeanFactory.BeanDefinitionMap加一个ImportConfig的BeanDefinition
register(componentClasses);
//刷新阶段
refresh();
//prepareRefresh 准备上下文
//obtainFreshBeanFactory 获取Bean工厂
//prepareBeanFactory Bean工厂初始化
//postProcessBeanFactory 后置处理Bean工厂,空方法,扩展点
//invokeBeanFactoryPostProcessors 执行BeanFactory的后置处理器。在这里
//扫描@Component那些BeanDefinition
//执行@Import的逻辑
//registerBeanPostProcessors 注册Bean的后置处理器,用于拦截Bean的创建
//initMessageSource 初始化消息源
//initApplicationEventMulticaster 初始化事件派发器,用来发布事件
//onRefresh 用来初始化一些特殊的Bean,目前默认是空方法,未实现
//registerListeners 注册监听器
//finishBeanFactoryInitialization 初始化所有剩余的单实例Bean(没有使用懒加载的Bean).整个Spring IOC的核心
//finishRefresh 发布事件
}
ConfigurationClassPostProcessor 是什么?
我们都知道,spring 容器管理了好多 bean, 方便了我们的开发,当我们用到某个实例的时候,不用一个一个的去 new 一个对象出来,而是直接从 Spring 容器里拿。可是 Spring 怎么把对应的 Class 一个个实例化为 bean 的呢?总体这个流程是分为两步,第一步是扫描出来所有需要由 Spring 容器管理的类并将其注册为 beanDefinition, 比如添加了@Component 注解,或者由@Import 引入的类,都会在第一步被扫描到,进而注册为 beanDefinition。第二步就是根据beanDifiniton 来把 bean 一个个创建出来。ConfigurationClassPostProcessor 就是做第一步的工作的,即扫描所有需要实例化的 bean 定义。
this()方法
调用父类构造方法,获取Bean工厂,默认DefaultListableBeanFactory
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
//省略其它代码
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
}
注册5个内置BeanDefinition
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
// ConfigurationClassPostProcessor实例会在bean工厂后置处理器调用时处理配置类
//通过@ComponentScan注解扫描需要生成BeanDefinition的类
//@PropertySource,@Import, @ImportResource,@Bean 注解也会被处理
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));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
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));
}
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));
}
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;
}
refresh()刷新方法
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
/**
* 1.准备上下文的刷新工作,记录bean容器的启动时间,容器活跃状态
* 验证系统中一些属性和属性值的设置等.
* 使用LinkedHashSet初始化earlyApplicationListeners和earlyApplicationEvents
*/
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
/**
* 2.获取Bean工厂,设置序列化id.
* 此处返回的beanFactory的真实类型为:DefaultListableBeanFactory
* 即前文上下文对象父类构造器生成的bean工厂
*
*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
/**
* 3.bean工厂的初始化准备工作,设置bean工厂的一些属性
* 比如:创建bean工厂时,需要忽略哪些接口,需要注册哪些bean,需要设置哪些Bean的后置处理器等.
*
* 例如常用的添加bean后置处理器:ApplicationContextAwareBeanPostProcessor, ApplicationListenerDetector
*
* 此外,注册一些和环境相关的bean单实例bean.
*/
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
/**
* 4.Bean定义加载完毕之后实现,目前方法为空实现,留给开发人员进行自定义扩展。
* 和BeanFactoryPostProcessor中的方法postProcessBeanFactory相同
*
* 该方法在Bean定义加载完毕之后,Bean实例化之前会执行
* 比如在BeanFactory加载完所有的Bean定义之后,想要修改某个bean的定义信息,可以通过重写这个方法实现.
* 比如:在xml中配置了<bean id="user"><property name="name" value="wb"></property></bean>
* 如果想在不修改配置文件的情况下修改name的值,可以使用如下的方法:
* class MyApplicationContext extends ClassPathXmlApplicationContext{
public MyApplicationContext(String s){
super(s);
}
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("user");
PropertyValue propertyValue=new PropertyValue("name", "www.so.com");
beanDefinition.getPropertyValues().addPropertyValue(propertyValue);
}
*/
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
/**
* 5.执行beanFactory的后置处理器
*
* 调用bean工厂的后置处理器,有两种 BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor
* BeanDefinitionRegistryPostProcessor优先级大于BeanFactoryPostProcessor
* BeanDefinitionRegistryPostProcessor内优先级是 new出来对象 > 实现PriorityOrdered接口对象 > 实现 * Ordered接口对象> 容器中对象
* BeanFactoryPostProcessor 同理
*
*
* 在这里,ConfigurationClassPostProcessor bean工厂的后置处理器将用户自定义的Bean
* 扫描为BeanDefinition,加入BeanFactory.beanDefinitionMap
* 配置类中的Selector类型的组件和@Component,@ComponentScan中的元数据信息也会在该步骤中进行解析
* 还包括执行条件注解@Condition的回调逻辑
*
* 注册@Import里的类成为BeanDefinition加入BeanFactory.beanDefinitionMap
* ImportBeanDefinitionRegistrar对应的registerBeanDefinitions方法也会在该步骤中调用,给容器中注册自定义的组件.
*
*
*/
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
/**
* 6. 注册所有bean的后置处理器,用于拦截Bean的创建
* 两类BeanPostProcessor和MergedBeanDefinitionPostProcessor
* BeanPostProcessor会被获取实例
* BeanPostProcessor也会被排序,
* PriorityOrdered->Ordered->普通的
*
* BeanPostProcessor优先级大于MergedBeanDefinitionPostProcessor,但是 * MergedBeanDefinitionPostProcessor的合并bean接口最先调用
* BeanPostProcessor内优先级是 new出来对象 > 实现PriorityOrdered接口对象 > 实现Ordered接口对象> 容器 * 中对象
*/
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
/**
* 7.初始化消息源
* 用来做国际化,消息绑定,消息解析等功能
* 一般在SpringMVC中会使用到.
*/
initMessageSource();
// Initialize event multicaster for this context.
/**
* 8.初始化事件派发器,用来发布事件
* 如果容器中有类型为ApplicationEventMulticaster的派发器组件,则直接获取使用
* 如果容器中没有,则默认创建一个类型为SimpleApplicationEventMulticaster的派发器并加入容器,供容器派发事件使用
*/
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
/**
* 9.用来初始化一些特殊的Bean,目前默认是空方法,未实现,可以通过继承AbstractApplicationContext类,
* 然后覆写该方法进行自定义特殊bean的初始化.
*
* 比如:AbstractRefreshableWebApplicationContext中onRefresh方法用来初始化主题能力.
*
* SpringBoot也是在改步骤中启动内嵌Tomcat容器的
*/
onRefresh();
// Check for listener beans and register them.
/**
* 10.注册监听器
* 将监听器绑定到广播器上,将监听器对应的beanName绑定到到第8步初始化的事件派发器中,
* 如果之前有发布的事件,则直接通过事件派发器将事件派发出去.
*/
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
/**
* 11.初始化所有剩余的单实例Bean(没有使用懒加载的Bean).整个Spring IOC的核心.
*
* 包括执行@PostConstruct标注的方法.
*
* 注意:SpringMVC的父子容器创建Bean的过程:
* SpringMVC中,存在着父容器和子容器。当父容器启动之后,会通过该方法将所有的Dao和Service对应的Bean创建出来,保存到beanFactory的单例缓存容器中
* 当子容器启动之后,也会通过该方法将所有的Controller,viewResolver,HandlerMapping对应的Bean创建出来,然后放入到beanFactory的单例缓存容器中.
*/
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
/**
* 12.发布事件。例如容器中的刷新事件:ContextRefreshedEvent就是在这一步中发布. SpringCloud在该步骤中会启动web服务
*
*/
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
BeanDefinition讲解和创建bean流程
BeanDefinition讲解
BeanDefinition 是用来描述 Bean 的,里面存放着关于 Bean 的一系列信息,比如 Bean 的作用域,Bean 所对应的 class, 是否懒加载,是否 Primary 等等。有了它 Spring 容器就掌握了实例化 bean 所需要的一些重要信息,Spring 才可以对其进行实例化。
这里你可能会想,Spring 实例化一个对象怎么这么复杂,我们自己实例化的时候,不就拿到对应的类,new 一下不就完事了么,哪里需要什么 beanDefinition, 而 Spring 容器的作用不就是替我们保存一些实例,我们需要的时候向他索取,那么它也 new 一堆对象保存着不就行了么。
其实问题也就出在 new 一堆对象这件事上,Spring容器管理着很多很多对象,比如你写一个@Component 注解,它就要实例化一个对象保存着,那么当你启动 Spring 容器的时候面对那么多要实例化的对象,它要先去实例化谁呢?比如说,你可能用了 @DepentOn 注解,就意味着一个 bean 是要优先于另外一个 bean 被实例化出来的。如果你用了@Lazy 注解,那么 Spring 容器启动的时候并不会实例化这个bean,而是等你真正问 Spring 容器要这个实例的时候,它才会给你创建一个 bean 出来。此外有的 bean是多例,而有的是单例,这样的话是不是发现只用一个类来 new 一个对象是不是根本满足不了上面的需求了。所以就有了 beanDefinition 的概念。它描述了 bean 的各种信息。使得 spring 容器能够很好的实例化管理 bean。
代码举例
实体类代码
public class User {
private String name;
private String sex;
public User() {
}
public User(String name, String sex) {
this.name = name;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
'}';
}
}
测试代码:
public class TestDefinitionMain {
public static void main(String[] args) {
//实例化一个容器
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
//实例化一个 beanDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition(User.class);
//注册 beanDefinition
beanFactory.registerBeanDefinition("user1", beanDefinition);
//从容器里获取 bean 实例,如果没有的话,会去创建一个 bean 并返回
User user1 = beanFactory.getBean("user1", User.class);
System.out.println(user1);
//也可以通过操作 beanDefinition, 传入构造方法的参数,进而影响实例化 bean
//实例化一个 beanDefinition
RootBeanDefinition beanDefinition2 = new RootBeanDefinition(User.class);
//添加构造方法的参数
ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
constructorArgumentValues.addIndexedArgumentValue(0, "cison");
constructorArgumentValues.addIndexedArgumentValue(1, "男");
beanDefinition2.setConstructorArgumentValues(constructorArgumentValues);
//注册bean定义
beanFactory.registerBeanDefinition("user2", beanDefinition2);
User user2 = beanFactory.getBean("user2", User.class);
System.out.println(user2);
}
}
运行结果如下,至此我们已经通过注册 bean 定义,进而在容器中实例化一个 bean:
User{name='null', sex='null'}
User{name='cison', sex='男'}
注册BeanDefinition和创建bean源码剖析
从上面实例代码可以看到,主要的两个方法为 beanFactory.registerBeanDefinition() 注册BeanDefinition和beanFactory.getBean()创建bean,分别剖析一下这两个方法到底做了什么。
注册BeanDefinition
点进去 beanFactory.registerBeanDefinition() ,源码如下:
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
//我们所用的是 RootBeanDefinition, 所以 if 条件这里不用考虑
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
//判断是否已经注册了该 bean 的 bean定义,很明显我们第一次注册,这里获取为空,故这个 if 条件也跳过
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
//这里判断bean是否已经开始创建,很明显这里第一次注册bean定义,是没有的进行创建的
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
}
else {
//最终逻辑会走到这里
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
else if (isConfigurationFrozen()) {
clearByTypeCache();
}
}
从上面可以看到,代码最终会走到如下代码段,由此可知,注册bean定义,其实就是在将bean定义的信息,保存到 bean 容器的两个局部变量里,其中 beanDefinitionMap 保存bean名称和bean定义的映射关系,beanDefinitionNames 保存所有bean的名称。
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
创建bean
beanFactory.getBean()
这是创建 bean 的方法,点进去可以看到如下代码
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
可以看到真正创建 bean 的方法为 doGetBean(),继续往下走
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
//该方法判断该 bean 是否有别名,如果有的话就转换一下名称
String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
//该方法从三级缓存里尝试获取 bean,因为当前是第一次创建,故返回值为 null, 故下面 if 逻辑不会进去
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
// 与下面的 prototype 的 bean 不同,如果创建单例 bean 的时候发现该 bean 正在被创建,这说明出现了循环依赖,但是并没有立刻抛出异常,而是会将当前还没有完全创建好的 bean 返回(当然这也可能会出现问题,后面文章再分析)
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// Spring 只解决了单例 bean 的循环依赖问题,如果是 prototype 类型的 bean 出现了循环依赖则会跑出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
// 如果当前容器没有获取到bean定义,则会尝试从父容器中获取
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 if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
// 如果当前容器和父容器中都有改bean定义,就会将二者合并一下
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 如果配置了 @Dependon, 那么就会创建它所依赖的 bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 如果互相dependson, 就会抛出异常,注意这里不是循环依赖,而是二者都标注了 @DependOn 对方的注解,都想让对方先创建出来
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
// 创建当前 bean 依赖的 bean, 也是调用 getBean 方法
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
if (mbd.isSingleton()) {
// 创建单例 bean, 其中 getSingleton 方法是创建 bean 之前进行一写预备工作,createBean 是一个回调方法,该方法是真正实例化 bean 的地方
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
//.. 省略部分处理异常代码
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// ....省略部分代码
return (T) bean;
}
通过以上代码及注释,我们会走到如下代码这一行,这里是获取 bean 定义的,那么怎么获取呢,由上面注册bean定义的流程可以猜测,因为注册bean定义的时候,其实是把 bean 定义放入到了容器的一个局部变量 beanDefinitionMap 里,那么当要获取 bean 定义的时候,最终应该也是是从beanDefinitionMap 中来根据名称获取bean定义的。下面我们就继续跟进下面这行代码,来验证我们的猜想。
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
点进去 getMergedLocalBeanDefinition 可以看到
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
//这一行是获取合并之后的 bean 定义的,因为我们目前没有涉及与父 bean 的合并,故获取到 null
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null && !mbd.stale) {
return mbd;
}
//最终会走到这一行
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
我们留意到最后一行调用方法的第二个参数,是调用另外一个方法的返回值,我们跟进getBeanDefinition(beanName)
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
//果然是你!!!
BeanDefinition bd = this.beanDefinitionMap.get(beanName);
if (bd == null) {
if (logger.isTraceEnabled()) {
logger.trace("No bean named '" + beanName + "' found in " + this);
}
throw new NoSuchBeanDefinitionException(beanName);
}
return bd;
}
我们可以看到,最终果然是从 beanDefinitionMap 中获取到的 bean 定义。至于getMergedBeanDefinition 方法,它是用来合并父亲和孩子之间的bean定义的,目前我们不需要,故暂不讨论。接着我们返回创建 bean 的主流程中去。
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
这里就得到了 bean 定义,然后接下来的核心代码如下
//首先从bean定义中获取 dependOn 信息, 在声明bean的时候可以使用 @Dependon 注解指定在哪些bean创建之后再创建当前bean,我们样例中没有配置,故这里获取到 null,
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);
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()) {
//单例bean的创建流程
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
由上也可以看到 beanDefinition 的作用,可以看到它存储了 bean 的 dependOn 信息和作用域信息,用于控制创建 bean 的流程, 接下来就是真正创建 bean 的流程了,getSingleton 传入bean名称和一个钩子函数,在 getSingleton 方法里有这个一行代码 singletonObject = singletonFactory.getObject(); 这就是调用钩子函数来创建bean实例,所以我们这里直接跟进钩子函数的 createBean(beanName, mbd, args) 方法
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 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.
//这里是常识创建代理对象,因为我们样例没有配置代理,故这里获取到 null
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 {
//创建普通 bean 的方法
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
上面这段代码有两段逻辑,先尝试创建代理对象,如果该 bean 需要被代理,那么就会创建代理对象成功并返回,否则就会进入下面创建普通 bean 的流程 doCreateBean(beanName, mbdToUse, args)
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//在这里通过构造器反射获取到对象实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//属性赋值,依赖注入
populateBean(beanName, mbd, instanceWrapper);
//初始化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);
}
}
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 " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
该方法里获得实例对象是这一行代码,它底层比较复杂,但是原理就是获取实例类的构造器,通过反射生成一个对象。至此,我们通过getBean()方法就得到了一个实例 bean,后续会有一些初始化,实例化,增强的逻辑,这里暂时就不展开了。
instanceWrapper = createBeanInstance(beanName, mbd, args);
模拟构造器反射生成对象实例
public class TestDefinitionMain {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//实例化一个容器
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
//实例化一个 beanDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition(User.class);
//注册 beanDefinition
beanFactory.registerBeanDefinition("user1", beanDefinition);
//从容器里获取 bean 实例,如果没有的话,会去创建一个 bean 并返回
User user1 = beanFactory.getBean("user1", User.class);
System.out.println(user1);
//也可以通过操作 beanDefinition, 传入构造方法的参数,进而影响实例化 bean
//实例化一个 beanDefinition
RootBeanDefinition beanDefinition2 = new RootBeanDefinition(User.class);
//添加构造方法的参数
ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
constructorArgumentValues.addIndexedArgumentValue(0, "cison");
constructorArgumentValues.addIndexedArgumentValue(1, "男");
beanDefinition2.setConstructorArgumentValues(constructorArgumentValues);
//注册bean定义
beanFactory.registerBeanDefinition("user2", beanDefinition2);
User user2 = beanFactory.getBean("user2", User.class);
System.out.println(user2);
//构造器反射获取实例 candidate.newInstance();
Constructor<?>[] candidates = User.class.getDeclaredConstructors();
for (Constructor candidate : candidates) {
int parameterCount = candidate.getParameterCount();
if (parameterCount == 0) {
//通过反射实例化对象
User user3 = (User) candidate.newInstance();
System.out.println("user3:" + user3);
} else {
//模拟解析参数
ConstructorArgumentValues paramValues = beanDefinition2.getConstructorArgumentValues();
Map<Integer, ConstructorArgumentValues.ValueHolder> indexedArgumentValues = paramValues.getIndexedArgumentValues();
Object[] args0 = new Object[2];
args0[0] = indexedArgumentValues.get(0).getValue();
args0[1] = indexedArgumentValues.get(1).getValue();
//通过反射实例化对象
User user4 = (User) candidate.newInstance(args0);
System.out.println("user4:" + user4);
}
}
}
}
执行结果
User{name='null', sex='null'}
User{name='cison', sex='男'}
user3:User{name='null', sex='null'}
user4:User{name='cison', sex='男'}
bean创建流程图
三级缓存如何解决循环依赖
什么是三级缓存
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
// 一级缓存。value装的是成品bean
/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 三级缓存。value装的是函数式接口的具体实例,核心就是里面的方法。因此可以简单地理解为装的就是一个lambda表达式
/** Cache of singleton factories: bean name to ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// 二级缓存。value装的是半成品bean
/** Cache of early singleton objects: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
}
执行流程简单描述
1.Bean实例化前会先查询缓存,判断Bean是否已经存在
2.Bean属性赋值前会先向三级缓存中放入一个lambda表达式,该表达式执行则会生成一个半成品Bean放入二级缓存
3.Bean初始化完成后将完整的Bean放入一级缓存,同时清空二、三级缓存
Bean实例化前
AbstractBeanFactory.doGetBean
Bean实例化前会从缓存里面获取Bean,防止重复实例化
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
String beanName = transformedBeanName(name);
Object beanInstance;
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
// …… 省略其它代码
DefaultSingletonBeanRegistry.getSingleton(String beanName, boolean allowEarlyReference)
我们看看这个获取的方法逻辑:
从一级缓存获取,获取到了,则返回
从二级缓存获取,获取到了,则返回
从三级缓存获取,获取到了,则执行三级缓存中的lambda表达式,将结果放入二级缓存,清除三级缓存
public Object getSingleton(String beanName) {
return this.getSingleton(beanName, true);
}
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 从一级缓存中获取Bean 获取到了则返回 没获取到继续
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
// 从二级缓存中获取Bean 获取到了则返回 没获取到则继续
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 加一把锁防止 线程安全 双重获取校验
synchronized(this.singletonObjects) {
// 从一级缓存中获取Bean 获取到了则返回 没获取到继续
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 从二级缓存中获取Bean 获取到了则返回 没获取到则继续
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
// 从三级缓存中获取 没获取到则返回
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 获取到了 执行三级缓存中的lambda表达式
singletonObject = singletonFactory.getObject();
// 并将结果放入二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
// 从三级缓存中移除
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
属性赋值/依赖注入前
AbstractAutowireCapableBeanFactory.doCreateBean
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 这里就是将一个lambda表达式放入了三级缓存,我们需要去看一下这个表达式是干什么的
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
DefaultSingletonBeanRegistry.addSingletonFactory
这里就是将一个lambda表达式放入了三级缓存,我们需要去看一下这个表达式是干什么的
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized(this.singletonObjects) {
// 一级缓存中不存在的话
if (!this.singletonObjects.containsKey(beanName)) {
// 将lambda表达式放入三级缓存
this.singletonFactories.put(beanName, singletonFactory);
// 清除二级缓存
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
AbstractAutowireCapableBeanFactory.getEarlyBeanReference
该方法说白了就是会判断该Bean是否需要被动态代理,两种返回结果:
不需要代理,返回未属性注入、未初始化的半成品Bean
需要代理,返回未属性注入、未初始化的半成品Bean的代理对象
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator var5 = this.getBeanPostProcessors().iterator();
// 遍历后置处理器
while(var5.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var5.next();
// 找到实现SmartInstantiationAwareBeanPostProcessor接口的
// 该接口getEarlyBeanReference方法什么时候会执行?
// AOP动态代理的时候 该方法执行就是判断该Bean是否需要被代理
// 需要代理则会创建代理对象返回
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor)bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
// 这个Object有两种情况,一是实例化后的半成品Bean,二是半成品Bean动态代理后的代理对象
return exposedObject;
}
注意:这里只是把lambda表达式放入了三级缓存,如果不从三级缓存中获取,这个表达式是不执行的,一旦执行了,就会把半成品Bean或者半成品Bean的代理对象放入二级缓存中了
初始化后
AbstractBeanFactory.doGetBean
这里注意啊,这个getSingleton方法传参传了个lambda表达式,会在getSingleton(String beanName, ObjectFactory<?> singletonFactory) 方法中调用这个lambda表达式,这个表达式内部就是Bean的实例化过程
// Create bean instance.
if (mbd.isSingleton()) {
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;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
DefaultSingletonBeanRegistry.getSingleton(beanName, singletonFactory)
这个方法与上面那个不一样,重载了,我们看一看这个方法
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
synchronized(this.singletonObjects) {
// 第一次进来这里获取肯定为null
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 省略................
try {
// 注意啊,这个就是执行外面那个传参的lambda表达式
// 所以这里才会跳到createBean方法那里去执行
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
// 省略................
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
this.afterSingletonCreation(beanName);
}
// 到了这说明Bean创建完了
if (newSingleton) {
// 这里就会把Bean放入一级缓存中了 同时清除二、三级缓存
this.addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
DefaultSingletonBeanRegistry.addSingleton
protected void addSingleton(String beanName, Object singletonObject) {
synchronized(this.singletonObjects) {
// 放入一级缓存
this.singletonObjects.put(beanName, singletonObject);
// 清除二、三级缓存
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
总结
整个过程就三个地方跟缓存有关,我们假设现在要实例化A这个Bean,看看缓存是怎么变化的:
实例化前,获取缓存判断(三个缓存中肯定没有A,获取为null,进入实例化流程)
实例化完成,属性注入前(往三级缓存中放入了一个lambda表达式,一、二级为null)
初始化完成(将A这个Bean放入一级缓存,清除二、三级缓存)
以上则是单个Bean生成过程中缓存的变化!!
流程图
以A注入B,B注入A为例:
流程为doCreateBean(A) ->addSingletonFactory(A)->populateBean(A) -> doCreateBean(B) ->addSingletonFactory(B) -> populateBean(B) ->getSingleton(A) -> B添加到IOC容器中->getSingleton(B) -> A添加的IOC容器中
addSingletonFactory:把lambda表达式放入了第三级缓存
A属性注入前就把lambda表达式放入了第三级缓存,所以B再注入A的时候会从第三级缓存中找到A的lambda表达式并执行,然后将半成品Bean放入第二级缓存,所以此时B注入的只是半成品的A对象,B创建完成后返回给A注入,A继续初始化,完成创建。
注意: B注入的半成品对象是A的代理对象,持有A的引用,所以之后A初始化完成后,B这个注入的代理对象,随着A对象的属性填充和初始化就变成了完整的A的代理对象,最终A初始化完成,会把A的代理对象的引用赋值给A暴露出去,A也就完成了创建
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);
}
}
// ……………………其它代码省略
为什么使用三级缓存,二级行不行
A是单例的,也就是要保证,在Spring中,使用到该bean的地方,都是同一个bean才行。但是每次执行singletonFactory.getObject()
都会产生新的代理对象。假设只有一级和三级缓存,每次从三级缓存中获取代理对象,都会产生新的代理对象,忽略性能不说,是不符合单例原则的。
所以这里我们要借助二级缓存来解决这个问题,将singleFactory.getObject()产生的对象放到二级缓存中去,后面直接从二级缓存中拿
,保证始终只有一个代理对象。
BeanFactory和FactoryBean的区别
**共同点:**都是接口
区别:
BeanFactory 以Factory结尾,表示它是一个工厂类,用于管理Bean的一个工厂。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。该接口是IoC容器的顶级接口,是IoC容器的最基础实现,也是访问Spring容器的根接口,负责对bean的创建,访问等工作
对FactoryBean而言,以Bean结尾,说明这是一个交给容器去管理的bean。这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似。
源码解析
public interface FactoryBean<T> {
String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
@Nullable
T getObject() throws Exception;
@Nullable
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}
AbstractFactory.doGetBean方法中,最后getObjectForBeanInstance方法都会对实例化的bean,进行判断是否为FactoryBean类型,如果是调用getObject获取修饰对象
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// 其余代码省略
// Create bean instance.
if (mbd.isSingleton()) {
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;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
}
进入getObjectForBeanInstance方法
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
//如果name不为null且以&开头进入if
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
//带&符号直接返回FactoryBean对象,不带执行下边getObjectFromFactoryBean方法返回真正实例
return beanInstance;
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
//不是FactoryBean对象直接返回
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
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());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
进入FactoryBeanRegistrySupport.getObjectFromFactoryBean方法
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (shouldPostProcess) {
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
beforeSingletonCreation(beanName);
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
else {
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
再进入doGetObjectFromFactoryBean
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//重点在这,调用getObject方法获取factoryBean封装的对象
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
if (object == null) {
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();
}
return object;
}