IOC思想解析
IOC(控制反转):全称为:Inverse of Control。从字面上理解就是控制反转了,将对在自身对象中的一个内置对象的控制反转,反转后不再由自己本身的对象进行控制这个内置对象的创建,而是由第三方系统去控制这个内置对象的创建。
DI(依赖注入):全称为Dependency Injection,意思自身对象中的内置对象是通过注入的方式进行创建。
那么IOC和DI这两者又是什么关系呢? IOC就是一种软件设计思想,DI是这种软件设计思想的一个实现。 把本来在类内部控制的对象,反转到类外部进行创建后注入,不再由类本身进行控制,这就是IOC的本质。
xml方式配置bean
利用<bean>标签进行注入
<bean id="..." class="..."> <constructor-arg index="0" value="..."></constructor-arg> <property name="..." value="..."></property> <property name="..."> <list> <value>...</value> <value>...</value> </list> </property> </bean>优点:
- 低耦合
- 对象关系清晰
- 集中管理
缺点:
- 配置繁琐
- 开发效率较低
- 文件解析耗时
注解方式配置bean
1、使用@Component声明
2、配置类中使用@Bean
3、实现FactoryBean
@Component public class MyCat implements FactoryBean<Animal> { @Override public Animal getObject() throws Exception { return new Cat(); } @Override public Class<?> getObjectType() { return Animal.class; } }4、实现BeanDefinitionRegistryPostProcessor
@Component public class MyBeanRegister implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException { RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(); rootBeanDefinition.setBeanClass(Dog.class); beanDefinitionRegistry.registerBeanDefinition("dog",rootBeanDefinition); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { } }5、实现ImportBeanDefinitionRegistry
public class MyBeanImport implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(); rootBeanDefinition.setBeanClass(Bird.class); registry.registerBeanDefinition("bird",rootBeanDefinition); } } @Component public class HelloService { @Autowired @Qualifier("bird") private Animal animal; public String hello(){ return animal.getName(); } } @RunWith(SpringRunner.class) @SpringBootTest @Import(MyBeanImport.class) public class ApplicationTest { @Autowired private HelloService helloService; @Test public void test(){ System.out.println(helloService.hello()); } }优点:
- 使用简单
- 开发效率高
- 高内聚
缺点:
- 配置分散
- 对象关系不清晰
- 修改配置需要重新编译工程
refresh方法解析
完成了SpringApplication的run方法:
public ConfigurableApplicationContext run(String... args) { // 计时工具 StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList(); this.configureHeadlessProperty(); // 第一步:获取并启动监听器 SpringApplicationRunListeners listeners = this.getRunListeners(args); listeners.starting(); Collection exceptionReporters; try { ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); // 第二步:根据SpringApplicationRunListeners以及参数来准备环境 ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments); this.configureIgnoreBeanInfo(environment); // 准备Banner打印器 - 就是启动Spring Boot的时候打印在console上的ASCII艺术字体 Banner printedBanner = this.printBanner(environment); // 第三步:创建Spring容器 context = this.createApplicationContext(); exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context); // 第四步:Spring容器前置处理 this.prepareContext(context, environment, listeners, applicationArguments, printedBanner); // 第五步:刷新容器 this.refreshContext(context); // 第六步:Spring容器后置处理 this.afterRefresh(context, applicationArguments); stopWatch.stop(); if (this.logStartupInfo) { (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch); } // 第七步:发出结束执行的事件 listeners.started(context); this.callRunners(context, applicationArguments); } catch (Throwable var10) { this.handleRunFailure(context, var10, exceptionReporters, listeners); throw new IllegalStateException(var10); } try { // 第八步:执行Runners listeners.running(context); // 返回容器 return context; } catch (Throwable var9) { this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null); throw new IllegalStateException(var9); } }- 第一步:获取并启动监听器
- 第二步:根据SpringApplicationRunListeners以及参数来准备环境
- 第三步:创建Spring容器
- 第四步:Spring容器前置处理
- 第五步:刷新容器
- 第六步:Spring容器后置处理
- 第七步:发出结束执行的事件
- 第八步:执行Runners
这里从创建Spring容器说起:
context = createApplicationContext();继续跟进该方法:
protected ConfigurableApplicationContext createApplicationContext() { Class<?> contextClass = this.applicationContextClass; if (contextClass == null) { try { switch (this.webApplicationType) { case SERVLET: contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS); break; case REACTIVE: contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS); break; default: contextClass = Class.forName(DEFAULT_CONTEXT_CLASS); } } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Unable create a default ApplicationContext, " + "please specify an ApplicationContextClass", ex); } } return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass); }这里创建容器的类型 还是根据webApplicationType进行判断的,该类型为SERVLET类型,所以会通过反射装载对应的字节码,也就是AnnotationConfigServletWebServerApplicationContext
第四步:Spring容器前置处理
这一步主要是在容器刷新之前的准备动作。包含一个非常关键的操作:将启动类注入容器,为后续开启自动化配置奠定基础。
prepareContext(context, environment, listeners, applicationArguments, printedBanner);继续跟进该方法:
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) { //设置容器环境,包括各种变量 context.setEnvironment(environment); //执行容器后置处理 postProcessApplicationContext(context); //执行容器中的ApplicationContextInitializer(包括 spring.factories和自定义的实例) applyInitializers(context); //发送容器已经准备好的事件,通知各监听器 listeners.contextPrepared(context); if (this.logStartupInfo) { logStartupInfo(context.getParent() == null); logStartupProfileInfo(context); } // Add boot specific singleton beans //注册启动参数bean,这里将容器指定的参数封装成bean,注入容器 ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); beanFactory.registerSingleton("springApplicationArguments", applicationArguments); //设置banner if (printedBanner != null) { beanFactory.registerSingleton("springBootBanner", printedBanner); } if (beanFactory instanceof DefaultListableBeanFactory) { ((DefaultListableBeanFactory) beanFactory) .setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding); } // Load the sources //获取我们的启动类指定的参数,可以是多个 Set<Object> sources = getAllSources(); Assert.notEmpty(sources, "Sources must not be empty"); //加载我们的启动类,将启动类注入容器 load(context, sources.toArray(new Object[0])); //发布容器已加载事件。 listeners.contextLoaded(context); }调用初始化器:
protected void applyInitializers(ConfigurableApplicationContext context) { // 1. 从SpringApplication类中的initializers集合获取所有的ApplicationContextInitializer for (ApplicationContextInitializer initializer : getInitializers()) { // 2. 循环调用ApplicationContextInitializer中的initialize方法 Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(), ApplicationContextInitializer.class); Assert.isInstanceOf(requiredType, context, "Unable to call initializer."); initializer.initialize(context); } }这里终于用到了在创建SpringApplication实例时设置的初始化器了,依次对它们进行遍历,并调用initialize方法。我们也可以自定义初始化器,并实现initialize方法,然后放入META-INF/spring.factories配置文件中Key为:org.springframework.context.ApplicationContextInitializer的value中,这里我们自定义的初始化器就会被调用,是我们项目初始化的一种方式
加载启动指定类(重点)
大家先回到文章最开始看看,在创建SpringApplication实例时,先将HelloWorldMainApplication.class存储在this.primarySources属性中,现在就是用到这个属性的时候了,我们来看看getAllSources()
public Set<Object> getAllSources() { Set<Object> allSources = new LinkedHashSet<>(); if (!CollectionUtils.isEmpty(this.primarySources)) { //获取primarySources属性,也就是之前存储的HelloWorldMainApplication.class allSources.addAll(this.primarySources); } if (!CollectionUtils.isEmpty(this.sources)) { allSources.addAll(this.sources); } return Collections.unmodifiableSet(allSources); }很明显,获取了this.primarySources属性,也就是我们的启动类HelloWorldMainApplication.class,我们接着看load(context, sources.toArray(new Object[0]));
protected void load(ApplicationContext context, Object[] sources) { if (logger.isDebugEnabled()) { logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources)); } BeanDefinitionLoader loader = createBeanDefinitionLoader(getBeanDefinitionRegistry(context), sources); if (this.beanNameGenerator != null) { loader.setBeanNameGenerator(this.beanNameGenerator); } if (this.resourceLoader != null) { loader.setResourceLoader(this.resourceLoader); } if (this.environment != null) { loader.setEnvironment(this.environment); } loader.load(); } private int load(Class<?> source) { if (isGroovyPresent() && GroovyBeanDefinitionSource.class.isAssignableFrom(source)) { // Any GroovyLoaders added in beans{} DSL can contribute beans here GroovyBeanDefinitionSource loader = BeanUtils.instantiateClass(source, GroovyBeanDefinitionSource.class); load(loader); } if (isComponent(source)) { //以注解的方式,将启动类bean信息存入beanDefinitionMap,也就是将Application.class存入了beanDefinitionMap this.annotatedReader.register(source); return 1; } return 0; }启动类Application.class被加载到 beanDefinitionMap中,后续该启动类将作为开启自动化配置的入口,后面一篇文章我会详细的分析,启动类是如何加载,以及自动化配置开启的详细流程。 通知监听器,容器已准备就绪
listeners.contextLoaded(context);主还是针对一些日志等监听器的响应处理。
第五步:刷新容器
refresh()方法刷新容器的步骤:
执行到这里,springBoot相关的处理工作已经结束,接下的工作就交给了spring。我们来看看refreshContext(context);
protected void refresh(ApplicationContext applicationContext) { Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext); //调用创建的容器applicationContext中的refresh()方法 ((AbstractApplicationContext) applicationContext).refresh(); } public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext { @Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. /** * 刷新上下文环境 * 容器状态设置 * 初始化属性设置 * 检查必备属性是否存在 */ prepareRefresh(); // Tell the subclass to refresh the internal bean factory. /** * 设置beanFactory序列化id * 获取BeanFactory;默认实现是DefaultListableBeanFactory,在创建容器的时候创建的 */ ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. /** * //BeanFactory的预准备工作 * BeanFactory进行一些设置,比如context的类加载器,BeanPostProcessor和XXXAware自动装配等 * 设置忽略的自动装配接口,以及注册一些组件 */ prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. /** * 提供子类覆盖的额外处理,即子类处理自定义的BeanFactoryPostProcess */ postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. /** * 激活各种BeanFactory处理器,包括BeanDefinitionRegistryBeanFactoryPostProcessor和普通的BeanFactoryPostProcessor * 执行对应的postProcessBeanDefinitionRegistry方法 和 postProcessBeanFactory方法 * 调用BeanDefinitionRegistryBeanFactoryPostProcessor实现向容器内添加bean的定义 * 调用BeanFactoryPostProcessor实现向容器内bean的定义添加属性 */ invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. /** * 注册拦截Bean创建的Bean处理器,即注册BeanPostProcessor,不是BeanFactoryPostProcessor,注意两者的区别 * 注意,这里仅仅是排序后注册,并不会执行对应的方法,将在bean的实例化时执行对应的方法 */ registerBeanPostProcessors(beanFactory); // Initialize message source for this context. /** * 初始化MessageSource组件(做国际化功能;消息绑定,消息解析); */ initMessageSource(); // Initialize event multicaster for this context. /** * 初始化上下文事件广播器,并放入applicatioEventMulticaster,如ApplicationEventPublisher */ initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. /** * 子类重写这个方法,在容器刷新的时候可以自定义逻辑;如创建Tomcat,Jetty等WEB服务器 */ onRefresh(); // Check for listener beans and register them. /** * 注册应用的监听器。就是注册实现了ApplicationListener接口的监听器bean, * 这些监听器是注册到ApplicationEventMulticaster中的 */ registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. /** * 初始化所有剩下的非懒加载的单例bean */ finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. /** * 完成context的刷新,初始化生命周期处理器,调用LifecycleProcessor的onRefresh()方法, * 并且发布事件(ContextRefreshedEvent) */ 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(); } } } }refresh方法在spring整个源码体系中举足轻重,是实现 ioc 和 aop的关键。
第六步:Spring容器后置处理
protected void afterRefresh(ConfigurableApplicationContext context, ApplicationArguments args) { }扩展接口,设计模式中的模板方法,默认为空实现。如果有自定义需求,可以重写该方法。比如打印一些启动结束log,或者一些其它后置处理。
第七步:发出结束执行的事件
public void started(ConfigurableApplicationContext context) { for (SpringApplicationRunListener listener : this.listeners) { //执行EventPublishingRunListener的started方法 listener.started(context); } } @Override public void started(ConfigurableApplicationContext context) { //创建ApplicationStartedEvent事件,并且发布事件 //我们看到是执行的ConfigurableApplicationContext这个容器的publishEvent方法,和前面的starting是不同的 context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context)); }获取EventPublishingRunListener监听器,并执行其started方法,并且将创建的Spring容器传进去了,创建一个ApplicationStartedEvent事件,并执行ConfigurableApplicationContext 的publishEvent方法,也就是说这里是在Spring容器中发布事件,并不是在SpringApplication中发布事件,和前面的starting是不同的,前面的starting是直接向SpringApplication中的11个监听器发布启动事件。
第八步:执行Runners
我们再来看看最后一步callRunners(context, applicationArguments);
private void callRunners(ApplicationContext context, ApplicationArguments args) { List<Object> runners = new ArrayList<>(); //获取容器中所有的ApplicationRunner的Bean实例 runners.addAll(context.getBeansOfType(ApplicationRunner.class).values()); //获取容器中所有的CommandLineRunner的Bean实例 runners.addAll(context.getBeansOfType(CommandLineRunner.class).values()); AnnotationAwareOrderComparator.sort(runners); for (Object runner : new LinkedHashSet<>(runners)) { if (runner instanceof ApplicationRunner) { //执行ApplicationRunner的run方法 callRunner((ApplicationRunner) runner, args); } if (runner instanceof CommandLineRunner) { //执行CommandLineRunner的run方法 callRunner((CommandLineRunner) runner, args); } } }如果是ApplicationRunner的话,则执行如下代码:
private void callRunner(ApplicationRunner runner, ApplicationArguments args) { try { (runner).run(args); } catch (Exception ex) { throw new IllegalStateException("Failed to execute ApplicationRunner", ex); } }如果是CommandLineRunner的话,则执行如下代码:
private void callRunner(CommandLineRunner runner, ApplicationArguments args) { try { (runner).run(args.getSourceArgs()); } catch (Exception ex) { throw new IllegalStateException("Failed to execute CommandLineRunner", ex); } }我们也可以自定义一些ApplicationRunner或者CommandLineRunner,实现其run方法,并注入到Spring容器中,在SpringBoot启动完成后,会执行所有的runner的run方法。
至此,SpringApplication大概分析了一遍。
bean实例化解析
finishBeanFactoryInitialization(beanFactory)方法会实例化所有剩余的非懒加载单例 bean。除了一些内部的 bean、实现了 BeanFactoryPostProcessor 接口的 bean、实现了 BeanPostProcessor 接口的 bean,其他的非懒加载单例 bean 都会在这个方法中被实例化,并且 BeanPostProcessor 的触发也是在这个方法中。
跟踪到AbstractApplicationContext.refresh()方法,找到代码finishBeanFactoryInitialization(beanFactory)查看实现。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this context. // 1.初始化此上下文的转换服务 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. // 2.如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析 if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. // 3.初始化LoadTimeWeaverAware Bean实例对象 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. // 4.冻结所有bean定义,注册的bean定义不会被修改或进一步后处理,因为马上要创建 Bean 实例对象了 beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons. // 5.实例化所有剩余(非懒加载)单例对象 beanFactory.preInstantiateSingletons(); }继续跟踪到DefaultListableBeanFactory#preInstantiateSingletons
@Override public void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { logger.trace("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. List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... //遍历beanNames,触发所有非懒加载单例bean的初始化 for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //Bean实例:不是抽象类 && 是单例 && 不是懒加载 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { //判断beanName对应的bean是否为FactoryBean if (isFactoryBean(beanName)) { //通过getBean(&beanName)拿到的是FactoryBean本身;通过getBean(beanName)拿到的是FactoryBean创建的Bean实例 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { final FactoryBean<?> factory = (FactoryBean<?>) bean; //判断这个FactoryBean是否希望急切的初始化 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) { //如果beanName对应的bean不是FactoryBean,只是普通Bean,通过beanName获取bean实例 getBean(beanName); } } } else { getBean(beanName); } } } // 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(); } } } }要理解FactoryBean和Bean的区别 一般情况下,Spring通过反射机制利用bean的class属性指定实现类来实例化 bean。而FactoryBean 是一种特殊的 bean,它是个工厂 bean,可以自己创建 bean 实例,如果一个类实现了FactoryBean 接口,则该类可以自己定义创建实例对象的方法,只需要实现它的 getObject() 方法。
注:很多中间件都利用 FactoryBean 来进行扩展。
引入了几个重要的缓存:
- mergedBeanDefinitions 缓存:beanName -> 合并的 bean 定义。
- beanDefinitionMap 缓存:beanName -> BeanDefinition。
- singletonObjects 缓存:beanName -> 单例 bean 对象。
- earlySingletonObjects 缓存:beanName -> 单例 bean 对象,该缓存存放的是早期单例 bean 对象,可以理解成还未进行属性填充、初始化。
- singletonFactories 缓存:beanName -> ObjectFactory。
- singletonsCurrentlyInCreation 缓存:当前正在创建单例 bean 对象的 beanName 集合。
继续跟踪到AbstractBeanFactory#doGetBean创建bean
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { //解析beanName,主要是解析别名、去掉FactoryBean的前缀“&” final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. //尝试从缓存中获取beanName对应的实例,通过缓存解决循环依赖问题 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { 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 + "'"); } } //返回beanName对应的实例对象(主要用于FactoryBean的特殊处理,普通Bean会直接返回sharedInstance本身) bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. // scope为prototype非单例的循环依赖校验:如果beanName已经正在创建Bean实例中,而此时我们又要再一次创建beanName的实例,则代表出现了循环依赖,需要抛出异常。 // 例子:如果存在A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为对于B的创建再次返回创建A,造成循环依赖 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. BeanFactory parentBeanFactory = getParentBeanFactory(); //如果parentBeanFactory存在,并且beanName在当前BeanFactory不存在Bean定义,则尝试从parentBeanFactory中获取bean实例 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) { //如果不是仅仅做类型检测,而是创建bean实例,这里要将beanName放到alreadyCreated缓存 markBeanAsCreated(beanName); } try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. //拿到当前bean依赖的bean名称集合,在实例化自己之前,需要先实例化自己依赖的bean,如使用@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); 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()) { //scope为singleton的bean创建(新建了一个ObjectFactory,并且重写了getObject方法,在里面创建bean 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; } }); //返回beanName对应的实例对象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //其它非单例的情况,暂不分析 ...... } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } return (T) bean; }查看DefaultSingletonBeanRegistry#getSingleton
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); synchronized (this.singletonObjects) { //首先检查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 + "'"); } //创建单例前的操作,把bean放入正准备创建的一个Set中singletonsCurrentlyInCreation,如果重复会报异常 //如果存在构造器循环依赖的时候(A(B b),B(C c),C(A a)),会在这点报出异常 beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { //执行singletonFactory的getObject方法获取bean实例,就是执行传入方法createBean 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; } //创建单例后的操作,在singletonsCurrentlyInCreation中移除 afterSingletonCreation(beanName); } if (newSingleton) { addSingleton(beanName, singletonObject); } } return singletonObject; } }继承跟踪AbstractAutowireCapableBeanFactory#createBean
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 { //验证及准备覆盖的方法(对override属性进行标记及验证) mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. //实例化前的处理,如果有实现InstantiationAwareBeanPostProcessor的BeanPostProcessor可以直接返回真正的bean实例 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实例(一般真正创建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); } }实例化前的处理,给 InstantiationAwareBeanPostProcessor 一个机会返回代理对象来替代真正的 bean 实例,从而跳过 Spring 默认的实例化过程,达到“短路”效果。会执行 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation 方法,该方法可以返回 bean 实例的代理,从而跳过 Spring 默认的实例化过程。
查看AbstractAutowireCapableBeanFactory#doCreateBean,这个方法非常重要
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { //根据beanName、mbd、args,使用对应的策略创建Bean实例,并返回包装类BeanWrappe 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. 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"); } //注意这点,曝光beanName的ObjectFactory,用于解决循环引用。 在开始通过doGetBean取值的时候调用了getSingleton就调用到这个工厂来了 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; try { //对bean进行属性填充;其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean实例 //设置属性,非常重要,比如使用@Autowired注入的值等 populateBean(beanName, mbd, instanceWrapper); //经过AOP处理,原生对象转换成了代理对象,跟进去 //执行后置处理器,aop就是在这里完成的处理 exposedObject = initializeBean(beanName, exposedObject, mbd); } ...... return exposedObject; }实例化对象createBeanInstance,就是选出一个策略来实例化一个对象, 那有什么策略呢? 这就看程序员是怎么配置的了, 程序员可以配置工厂方法,指定构造方法,或者是程序员没有做出任何干涉,让Spring按自己的方式去实例化
BeanDefinition介绍
- 一个对象在Spring中的描述,RootBeanDefinition是其常见实现
- 通过操作BeanDefinition来完成bean实例化和属性注入
BeanDefinition类图
自定义创建Bean
实例化流程
参考: https://www.cnblogs.com/java-chen-hao/p/11829344.html
https://www.cnblogs.com/grasp/p/11942735.html
https://www.cnblogs.com/grasp/p/11971887.html