1.为什么要有springboot
1.1spring的优缺点
长处:提供了ioc和aop等弱小的性能让开发人员专一业务代码
毛病:配置简单,我的项目依赖繁琐,依赖版本稍有不对就会造成兼容问题
2.springboot如何解决这些问题
2.1起步依赖:只需依赖一个我的项目就可达到spring依赖多个包的性能,行将具备某种性能的坐标打包到一起。
两个外围依赖spring-boot-starter-parent和spring-boot-starter-web:
spring-boot-starter-parent指定jar包版本
spring-boot-starter-web指定web开发jar包
2.2主动配置:只需引入相干的包,springboot会在启动时将这些配置的bean给初始化
通过在main函数加上注解@SpringBootApplication,该注解次要蕴含三个要害注解
· @configuration注解:代表它是一个配置类,咱们能够在该类中申明一些办法,返回bean
· @EnableAutoConfiguration:初始化bean
• @Import(AutoConfigurationImportSelector.class) : 实现主动配置的性能,从classpath下所有jar包的META-INF\spring-autoconfigure-metadata.properties拿到指定的bean初始化限度条件,而后从spring.factories里拿到指定的类初始化bean,进行初始化。
其余注解:
• @AutoConfigurationPackage:实例化启动类所在包上面的所有bean
· @ComponentScan:指定扫描包范畴,配和@AutoConfigurationPackage应用,可过滤不想初始化的bean
3.具体实现
看启动函数:
@SpringBootApplication public class DemoApplication{ public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
3.1构造函数
public SpringApplication(ResourceLoader resourceLoader, Object... sources) { this.resourceLoader = resourceLoader; initialize(sources); }
进入initialize办法
private void initialize(Object[] sources) { if (sources != null && sources.length > 0) { this.sources.addAll(Arrays.asList(sources)); } this.webEnvironment = deduceWebEnvironment(); setInitializers((Collection) getSpringFactoriesInstances( ApplicationContextInitializer.class)); setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass = deduceMainApplicationClass(); }
进入deduceWebEnvironment
private boolean deduceWebEnvironment() { for (String className : WEB_ENVIRONMENT_CLASSES) { if (!ClassUtils.isPresent(className, null)) { return false; } } return true; }
此办法是用来判断以后利用是什么类型:
private static final String[] WEB_ENVIRONMENT_CLASSES = { "javax.servlet.Servlet", "org.springframework.web.context.ConfigurableWebApplicationContext" };
须要下面两个类都存在才阐明以后是个web利用.
再看setInitializers和setListeners办法,都调用了getSpringFactoriesInstances办法:
private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // Use names and ensure unique to protect against duplicates Set<String> names = new LinkedHashSet<String>( SpringFactoriesLoader.loadFactoryNames(type, classLoader)); List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names); AnnotationAwareOrderComparator.sort(instances); return instances; }
getSpringFactoriesInstances办法是扫描门路下所有META-INF\spring.factories里
合乎type参数指定的接口的实现类并实例化,而后排序。
最初this.mainApplicationClass = deduceMainApplicationClass()找出启动main函数在的主类。
3.2run办法
public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; FailureAnalyzers analyzers = null; configureHeadlessProperty(); SpringApplicationRunListeners listeners = getRunListeners(args); listeners.started(); try { ApplicationArguments applicationArguments = new DefaultApplicationArguments( args); ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); Banner printedBanner = printBanner(environment); context = createApplicationContext(); analyzers = new FailureAnalyzers(context); prepareContext(context, environment, listeners, applicationArguments, printedBanner); refreshContext(context); afterRefresh(context, applicationArguments); listeners.finished(context, null); stopWatch.stop(); if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass) .logStarted(getApplicationLog(), stopWatch); } return context; } catch (Throwable ex) { handleRunFailure(context, listeners, analyzers, ex); throw new IllegalStateException(ex); } }
首先看getRunListeners办法:
private SpringApplicationRunListeners getRunListeners(String[] args) { Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class }; return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances( SpringApplicationRunListener.class, types, this, args));}
同样是找到并实例化SpringApplicationRunListener的实现类;
再看listeners.started()做了什么:
一路跟进去
最终调用了listener.onApplicationEvent(event)办法,该办法有很多子类的实现,内容大略就是做一些筹备工作,比方org.springframework.boot.context.logging.LoggingApplicationListener做的就是
private void onApplicationStartedEvent(ApplicationStartedEvent event) { this.loggingSystem = LoggingSystem .get(event.getSpringApplication().getClassLoader()); this.loggingSystem.beforeInitialize(); }
日志初始化的一些筹备工作。
接下来看
ApplicationArguments applicationArguments = new DefaultApplicationArguments( args);
初始化main函数的参数;
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
private ConfigurableEnvironment prepareEnvironment( SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) { // Create and configure the environment ConfigurableEnvironment environment = getOrCreateEnvironment(); configureEnvironment(environment, applicationArguments.getSourceArgs()); listeners.environmentPrepared(environment); if (isWebEnvironment(environment) && !this.webEnvironment) { environment = convertToStandardEnvironment(environment); } return environment; }
进入getOrCreateEnvironment:
private ConfigurableEnvironment getOrCreateEnvironment() { if (this.environment != null) { return this.environment; } if (this.webEnvironment) { return new StandardServletEnvironment(); } return new StandardEnvironment(); }
个别都是webEnvironment,所以返回new StandardServletEnvironment();
protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) { configurePropertySources(environment, args); configureProfiles(environment, args); }
protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) { MutablePropertySources sources = environment.getPropertySources(); if (this.defaultProperties != null && !this.defaultProperties.isEmpty()) { sources.addLast( new MapPropertySource("defaultProperties", this.defaultProperties)); } if (this.addCommandLineProperties && args.length > 0) { String name = CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME; if (sources.contains(name)) { PropertySource<?> source = sources.get(name); CompositePropertySource composite = new CompositePropertySource(name); composite.addPropertySource(new SimpleCommandLinePropertySource( name + "-" + args.hashCode(), args)); composite.addPropertySource(source); sources.replace(name, composite); } else { sources.addFirst(new SimpleCommandLinePropertySource(args)); } } }
defaultProperties 是额定属性配置,能够在结构SpringBootApplication时通过setDefaultProperties设置;
如果配置了args,且命令行有名为commandLineArgs的参数,则会用命令行参数替换或新增该PropertySource。
再看configureProfiles,我的版本是个空办法(spring-boot-2.7.3)
看了下其余版本的,大略就是读取properties里的key为spring.profiles.active的配置项,配置到Environment。
持续看ConfigurationPropertySources.attach(environment)
/** * Attach a {@link ConfigurationPropertySource} support to the specified * {@link Environment}. Adapts each {@link PropertySource} managed by the environment * to a {@link ConfigurationPropertySource} and allows classic * {@link PropertySourcesPropertyResolver} calls to resolve using * {@link ConfigurationPropertyName configuration property names}. * <p> * The attached resolver will dynamically track any additions or removals from the * underlying {@link Environment} property sources. * @param environment the source environment (must be an instance of * {@link ConfigurableEnvironment}) * @see #get(Environment) */ public static void attach(Environment environment) { Assert.isInstanceOf(ConfigurableEnvironment.class, environment); MutablePropertySources sources = ((ConfigurableEnvironment) environment).getPropertySources(); PropertySource<?> attached = getAttached(sources); if (attached == null || !isUsingSources(attached, sources)) { attached = new ConfigurationPropertySourcesPropertySource(ATTACHED_PROPERTY_SOURCE_NAME, new SpringConfigurationPropertySources(sources)); } sources.remove(ATTACHED_PROPERTY_SOURCE_NAME); sources.addFirst(attached); }
该办法将ConfigurationPropertySource和environment绑定起来。
listeners.environmentPrepared(bootstrapContext, environment)办法为监听器筹备环境,过程有点简单,当前再看。
DefaultPropertiesPropertySource.moveToEnd(environment)将默认环境移到最初,这样优先级最高?
bindToSpringApplication(environment)将环境和主类绑定。
if (!this.isCustomEnvironment) { EnvironmentConverter environmentConverter = new EnvironmentConverter(getClassLoader()); environment = environmentConverter.convertEnvironmentIfNecessary(environment, deduceEnvironmentClass()); }
将环境转化为规范环境
environment为ApplicationServletEnvironment,是StandEnvironment的子类,不必转。
ConfigurationPropertySources.attach(environment)再绑定一次环境和source。
prepareEnvironment完结了,再看configureIgnoreBeanInfo(environment):
private void configureIgnoreBeanInfo(ConfigurableEnvironment environment) { if (System.getProperty(CachedIntrospectionResults.IGNORE_BEANINFO_PROPERTY_NAME) == null) { Boolean ignore = environment.getProperty(CachedIntrospectionResults.IGNORE_BEANINFO_PROPERTY_NAME, Boolean.class, Boolean.TRUE); System.setProperty(CachedIntrospectionResults.IGNORE_BEANINFO_PROPERTY_NAME, ignore.toString()); } }
将environment的spring.beaninfo.ignore的值设置到零碎属性。
Banner printedBanner = printBanner(environment);
打印banner,
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.2.5.RELEASE)
如上图所示的,是咱们每次启动 SpringBoot 我的项目时就会在控制器输入的内容,这个就是 Banner 。这部分代码不重要。context = createApplicationContext();
/** * {@link ApplicationContextFactory} registered in {@code spring.factories} to support * {@link AnnotationConfigServletWebServerApplicationContext}. */ static class Factory implements ApplicationContextFactory { @Override public ConfigurableApplicationContext create(WebApplicationType webApplicationType) { return (webApplicationType != WebApplicationType.SERVLET) ? null : new AnnotationConfigServletWebServerApplicationContext(); } }
创立了一个AnnotationConfigServletWebServerApplicationContext。
AnnotationConfigServletWebServerApplicationContext继承自GenericApplicationContext,
/** * Create a new GenericApplicationContext. * @see #registerBeanDefinition * @see #refresh */ public GenericApplicationContext() { this.beanFactory = new DefaultListableBeanFactory(); }
父类实例化的时候创立了一个DefaultListableBeanFactory。
子类是泪花的时候创立了AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner,这两个类是用来读取condition注解和定义哪些类应该被实例化(@Component,@Service,@Resources这种)
/** * Create a new {@link AnnotationConfigServletWebServerApplicationContext} with the * given {@code DefaultListableBeanFactory}. The context needs to be populated through * {@link #register} calls and then manually {@linkplain #refresh refreshed}. * @param beanFactory the DefaultListableBeanFactory instance to use for this context */public AnnotationConfigServletWebServerApplicationContext(DefaultListableBeanFactory beanFactory) { super(beanFactory); this.reader = new AnnotatedBeanDefinitionReader(this); this.scanner = new ClassPathBeanDefinitionScanner(this);}
接下来 prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner):
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) { //注入环境属性 context.setEnvironment(environment); //上下文后置解决 this.postProcessApplicationContext(context); //欠缺初始化类的属性 this.applyInitializers(context); //发送监听事件 listeners.contextPrepared(context); //日志 if (this.logStartupInfo) { this.logStartupInfo(context.getParent() == null); this.logStartupProfileInfo(context); } //注册传入的配置参数为bean,这里将传入的参数封装成applicationArguments,外部相似命令行 ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); beanFactory.registerSingleton("springApplicationArguments", applicationArguments); //banner打印 if (printedBanner != null) { beanFactory.registerSingleton("springBootBanner", printedBanner); } //这里默认状况下bean定义不容许反复 if (beanFactory instanceof DefaultListableBeanFactory) { ((DefaultListableBeanFactory)beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding); } //默认不开启提早加载 if (this.lazyInitialization) { context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor()); } //获取全副的资源 //这里获取了启动类的资源和 以后SpringApplication中的source资源。 //到目前来说实际上只有启动类资源 Set<Object> sources = this.getAllSources(); Assert.notEmpty(sources, "Sources must not be empty"); this.load(context, sources.toArray(new Object[0])); listeners.contextLoaded(context);}
后置解决context
protected void postProcessApplicationContext(ConfigurableApplicationContext context) { // 是否自定义bean名称生成类 if (this.beanNameGenerator != null) { context.getBeanFactory().registerSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerator", this.beanNameGenerator); } //是否指定类加载器 if (this.resourceLoader != null) { if (context instanceof GenericApplicationContext) { ((GenericApplicationContext)context).setResourceLoader(this.resourceLoader); } if (context instanceof DefaultResourceLoader) { ((DefaultResourceLoader)context).setClassLoader(this.resourceLoader.getClassLoader()); } } //是否增加数据转换器 //在初始化环境对象的时候也有用到,这里能够间接通过 context.getEnvironment().getConversionService()获取到 if (this.addConversionService) { context.getBeanFactory().setConversionService(ApplicationConversionService.getSharedInstance()); } }
剩下的都是做一些筹备工作。
refreshContext(重点):
@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. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. 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(); } } }
首先看prepareRefresh()办法:
@Overrideprotected void prepareRefresh() { this.scanner.clearCache(); super.prepareRefresh();}
scnner清了缓存,父类prepareRefresh办法什么都没做;
再看obtainFreshBeanFactory:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; } @Override protected final void refreshBeanFactory() throws IllegalStateException { if (!this.refreshed.compareAndSet(false, true)) { throw new IllegalStateException( "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once"); } this.beanFactory.setSerializationId(getId()); } @Override public final ConfigurableListableBeanFactory getBeanFactory() { return this.beanFactory; }
refreshBeanFactory办法设置了一下id,getBeanFactory办法获取下面创立的factory。
接着看prepareBeanFactory办法:
/** * Configure the factory's standard context characteristics, * such as the context's ClassLoader and post-processors. * @param beanFactory the BeanFactory to configure */ protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // Tell the internal bean factory to use the context's class loader etc. beanFactory.setBeanClassLoader(getClassLoader()); if (!shouldIgnoreSpel) { beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); } beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // Configure the bean factory with context callbacks. beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class); // BeanFactory interface not registered as resolvable type in a plain factory. // MessageSource registered (and found for autowiring) as a bean. beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // Register early post-processor for detecting inner beans as ApplicationListeners. beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // Detect a LoadTimeWeaver and prepare for weaving, if found. if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } // Register default environment beans. if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) { beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup()); } }
首先疏忽一些主动注入;而后减少一些主动注入的依赖(一个接口有多个实现类时,用这里指定的实现类);而后减少ApplicationListenerDetector的BeanPostProcessor,而后注册一些环境单例bean。
而后再看postProcessBeanFactory:
这是个空办法,由子类实现,以后实现的子类是AnnotationConfigServletWebServerApplicationContext:
@Override protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { super.postProcessBeanFactory(beanFactory); if (this.basePackages != null && this.basePackages.length > 0) { this.scanner.scan(this.basePackages); } if (!this.annotatedClasses.isEmpty()) { this.reader.register(ClassUtils.toClassArray(this.annotatedClasses)); } } /**
super.postProcessBeanFactory(beanFactory):
/** * Register ServletContextAwareProcessor. * @see ServletContextAwareProcessor */ @Override protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this)); beanFactory.ignoreDependencyInterface(ServletContextAware.class); registerWebApplicationScopes(); }
减少了一个后置处理器,疏忽主动注入;
再看registerWebApplicationScopes:
/** * Register web-specific scopes ("request", "session", "globalSession", "application") * with the given BeanFactory, as used by the WebApplicationContext. * @param beanFactory the BeanFactory to configure * @param sc the ServletContext that we're running within */public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory, @Nullable ServletContext sc) { beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope()); beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope()); if (sc != null) { ServletContextScope appScope = new ServletContextScope(sc); beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope); // Register as ServletContext attribute, for ContextCleanupListener to detect it. sc.setAttribute(ServletContextScope.class.getName(), appScope); } beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory()); beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory()); beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory()); beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory()); if (jsfPresent) { FacesDependencyRegistrar.registerFacesDependencies(beanFactory); }}
将web申请的几种类型注册;
再回到后面:
if (this.basePackages != null && this.basePackages.length > 0) { this.scanner.scan(this.basePackages); } if (!this.annotatedClasses.isEmpty()) { this.reader.register(ClassUtils.toClassArray(this.annotatedClasses)); }
此处scan不是扫描@ComponentScan指定的包,意义暂不明;
接着看invokeBeanFactoryPostProcessors(重点),正文在代码中.
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // Invoke BeanDefinitionRegistryPostProcessors first, if any. Set<String> processedBeans = new HashSet<>(); //如果beanFactory是BeanDefinitionRegistry,那先调用beanFactoryPostProcessors中和beanFactory存在的 //类型为BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry //而后调用beanFactoryPostProcessors的postprocessBeanFactory办法 //优先级PriorityOrdered->Ordered->其余 if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! // Separate between BeanDefinitionRegistryPostProcessors that implement // PriorityOrdered, Ordered, and the rest. List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. boolean reiterate = true; while (reiterate) { reiterate = false; postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); reiterate = true; } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); } // Now, invoke the postProcessBeanFactory callback of all processors handled so far. invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { // Invoke factory processors registered with the context instance. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } //而后调用beanFacyory中类型为BeanFactoryPostProcessor的postProcessBeanFactory办法,因为BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子类 // 所以第一步中解决过的要过滤 // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); // Separate between BeanFactoryPostProcessors that implement PriorityOrdered, // Ordered, and the rest. List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { // skip - already processed in first phase above } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // Next, invoke the BeanFactoryPostProcessors that implement Ordered. List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // Finally, invoke all other BeanFactoryPostProcessors. List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); // Clear cached merged bean definitions since the post-processors might have // modified the original metadata, e.g. replacing placeholders in values... beanFactory.clearMetadataCache(); }
invokeBeanFactoryPostProcessors办法完结,就是调用了beanFactoryPostProcessors,接着看registerBeanPostProcessors:
/* Register bean processors that intercept bean creation. 注册BeanPostProcessor(Bean的后置处理器),在创立bean的前后等执行 */ public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { //获取所有postProcessor的名称 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)); // Separate between BeanPostProcessors that implement PriorityOrdered, // Ordered, and the rest. List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); //存储PriorityOrdered.class的postProcessor List<BeanPostProcessor> internalPostProcessors = new ArrayList<>(); //存储Ordered.class的postProcessor List<String> orderedPostProcessorNames = new ArrayList<>(); //存储其余的postProcessor List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { //优先级最高 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); priorityOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } //优先级第二 else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { //优先级最末 nonOrderedPostProcessorNames.add(ppName); } } // First, register the BeanPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); //注册PriorityOrdered.class的BeanPostProcessors,所谓注册就是外部的List<BeanPostProcessor> beanPostProcessors对象加上这个BeanPostProcessor //在这之前这个bean只作为一个一般bean存在于beanFactory registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // Next, register the BeanPostProcessors that implement Ordered. //注册Ordered.class的BeanPostProcessors, List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(); for (String ppName : orderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } sortPostProcessors(orderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, orderedPostProcessors); // Now, register all regular BeanPostProcessors. List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(); for (String ppName : nonOrderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); // Finally, re-register all internal BeanPostProcessors. //注册其余的BeanPostProcessors, sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors); // Re-register post-processor for detecting inner beans as ApplicationListeners, // moving it to the end of the processor chain (for picking up proxies etc). beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); }
上面是initMessageSource,不是重点,先不看
/* Initialize message source for this context. 初始化MessageSource组件(做国际化性能;音讯绑定,音讯解析); */ initMessageSource();
initApplicationEventMulticaster也不是重点,先不看
/* Initialize event multicaster for this context. 初始化事件派发器 */ initApplicationEventMulticaster();
onFresh,空办法,交给子类实现
/* Initialize other special beans in specific context subclasses. 子类重写这个办法,在容器刷新的时候能够自定义逻辑;如创立Tomcat,Jetty等WEB服务器 */ onRefresh();
registerListener,先不看
/* Check for listener beans and register them. 注册利用的监听器。就是注册实现了ApplicationListener接口的监听器bean */ registerListeners();
finishBeanFactoryInitialization(重点):
/* Instantiate all remaining (non-lazy-init) singletons. 初始化所有剩下的非懒加载的单例bean 初始化创立非懒加载形式的单例Bean实例(未设置属性) 填充属性 初始化办法调用(比方调用afterPropertiesSet办法、init-method办法) 调用BeanPostProcessor(后置处理器)对实例bean进行后置解决 */ finishBeanFactoryInitialization(beanFactory); /** * Finish the initialization of this context's bean factory, * initializing all remaining singleton beans. * 完结 bean factory 的初始化工作 * 实例化所有单例bean */ protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } // Stop using the temporary ClassLoader for type matching. beanFactory.setTempClassLoader(null); // Allow for caching all bean definition metadata, not expecting further changes. beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons. // 实例化所有立刻加载的单例bean beanFactory.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. // 所有bean的名字 List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... // 触发所有非提早加载单例bean的初始化,次要步骤为getBean for (String beanName : beanNames) { // 合并父BeanDefinition对象 // map.get(beanName) RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); // 如果是FactoryBean则加& 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); } } } else { // 实例化以后bean 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(); } } } }
看getBean办法,调用的是org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String):
@Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); } /** * Return an instance, which may be shared or independent, of the specified bean. * @param name the name of the bean to retrieve * @param requiredType the required type of the bean to retrieve * @param args arguments to use when creating a bean instance using explicit arguments * (only applied when creating a new instance as opposed to retrieving an existing one) * @param typeCheckOnly whether the instance is obtained for a type check, * not for actual use * @return an instance of the bean * @throws BeansException if the bean could not be created */ @SuppressWarnings("unchecked") protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { // 解析beanName 如果以&结尾去掉&结尾,如果是别名获取到真正的名字 final String beanName = transformedBeanName(name); Object bean; // 单纯了解尝试从缓存中获取 bean 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 + "'"); } } // 针对 FactoryBean 的解决 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // 如果是prototype类型且开启容许循环依赖,则抛出异样 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. // 查看父工厂中是否存在该对象 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); } else 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 属性 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current 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); try { getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // 创立单例bean if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { // 创立 bean 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); } else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } // Check if required type matches the type of the actual bean instance. 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.isTraceEnabled()) { logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; }
先从缓存中获取:
// 单纯了解尝试从缓存中获取 bean Object sharedInstance = getSingleton(beanName); /** * Return the (raw) singleton object registered under the given name. * <p>Checks already instantiated singletons and also allows for an early * reference to a currently created singleton (resolving a circular reference). * @param beanName the name of the bean to look for * @param allowEarlyReference whether early references should be created or not * @return the registered singleton object, or {@code null} if none found */ @Nullable protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return singletonObject; }
这里用到了三级缓存,一级一级获取,如果从三级缓存获取到了则放入二级缓存,从三级缓存移除。
如果获取不到,则调用getSingleton办法:
// 创立单例bean if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { // 创立 bean 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); }/** * Return the (raw) singleton object registered under the given name, * creating and registering a new one if none registered yet. * @param beanName the name of the bean * @param singletonFactory the ObjectFactory to lazily create the singleton * with, if necessary * @return the registered singleton object */ 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) { // 是否正在销毁,异样 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正在被创立,因为spingbean创立过程简单,步骤很多,须要标识 beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { // 传进来的调用,lamda表达式应用 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) { addSingleton(beanName, singletonObject); } } return singletonObject; } }
看看 singletonFactory.getObject()办法,也就是传参的lamda表达式的createBean()办法:
// 传进来的调用,lamda表达式应用 singletonObject = singletonFactory.getObject(); /** * Central method of this class: creates a bean instance, * populates the bean instance, applies post-processors, etc. * @see #doCreateBean */ @Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isTraceEnabled()) { logger.trace("Creating instance of bean '" + beanName + "'"); } // 拿到Bd 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. 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); } }
进入doCreateBean:
/** * Actually create the specified bean. Pre-creation processing has already happened * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks. * <p>Differentiates between default bean instantiation, use of a * factory method, and autowiring a constructor. * @param beanName the name of the bean * @param mbd the merged bean definition for the bean * @param args explicit arguments to use for constructor or factory method invocation * @return a new instance of the bean * @throws BeanCreationException if the bean could not be created * @see #instantiateBean * @see #instantiateUsingFactoryMethod * @see #autowireConstructor */ protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { // 创立 Bean 实例,仅仅调用构造方法,然而尚未设置属性 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"); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // 初始化bean实例 Object exposedObject = bean; try { // Bean属性填充 populateBean(beanName, mbd, instanceWrapper); // 调用初始化办法,利用BeanPostProcessor后置处理器 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 " + "'getBeanNamesOfType' 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; }
查看populateBean办法:
/** * Populate the bean instance in the given BeanWrapper with the property values * from the bean definition. * @param beanName the name of the bean * @param mbd the bean definition for the bean * @param bw the BeanWrapper with bean instance */ @SuppressWarnings("deprecation") // for postProcessPropertyValues 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. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return; } } } } PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); int resolvedAutowireMode = mbd.getResolvedAutowireMode(); if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null; if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { return; } } pvs = pvsToUse; } } } if (needsDepCheck) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } checkDependencies(beanName, mbd, filteredPds, pvs); } if (pvs != null) { applyPropertyValues(beanName, mbd, bw, pvs); } }
始终到DependencyDescriptor的resolveCandidate办法
resolveCandidate:276, DependencyDescriptor (org.springframework.beans.factory.config)doResolveDependency:1391, DefaultListableBeanFactory (org.springframework.beans.factory.support)resolveDependency:1311, DefaultListableBeanFactory (org.springframework.beans.factory.support)resolveFieldValue:656, AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement (org.springframework.beans.factory.annotation)inject:639, AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement (org.springframework.beans.factory.annotation)inject:119, InjectionMetadata (org.springframework.beans.factory.annotation)postProcessProperties:399, AutowiredAnnotationBeanPostProcessor (org.springframework.beans.factory.annotation)populateBean:1431, AbstractAutowireCapableBeanFactory
/** * Resolve the specified bean name, as a candidate result of the matching * algorithm for this dependency, to a bean instance from the given factory. * <p>The default implementation calls {@link BeanFactory#getBean(String)}. * Subclasses may provide additional arguments or other customizations. * @param beanName the bean name, as a candidate result for this dependency * @param requiredType the expected type of the bean (as an assertion) * @param beanFactory the associated factory * @return the bean instance (never {@code null}) * @throws BeansException if the bean could not be obtained * @since 4.3.2 * @see BeanFactory#getBean(String) */ public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) throws BeansException { return beanFactory.getBean(beanName); }
又调了一次getBean去获取援用的bean,如果此bean也援用了下面的bean会怎么样?设第一次实例化的bean为A,A援用B,B同时援用A,A填充属性B的时候发现B没有实例化,就会去实例化B,B填充属性A的时候去缓存拿,因为A曾经放到三级缓存了,那么就会拿出A,把A从三级缓存删除,放到二级缓存中,这样B就实例化好了,B实例化好后会把本人放入以及缓存,从二级和三级缓存删除,而后回到A的流程,A填充完B,这样A也实例化好了。
为什么须要三级缓存,集体感觉一级其实也够用,不过一级的缓存中可能会有为填充属性的bean,这样spring某些中央获取到可能有问题,那么至多要两级,一级放齐全实例化好的,二级放未填充属性的,第三级的作用是因为有些bean可能会须要被代理,A援用B,这个B应该是个代理类,所以须要第三级缓存来把B变成代理类:
if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); }
/** * Obtain a reference for early access to the specified bean, * typically for the purpose of resolving a circular reference. * @param beanName the name of the bean (for error handling purposes) * @param mbd the merged bean definition for the bean * @param bean the raw bean instance * @return the object to expose as bean reference */ protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { Object exposedObject = bean; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) { exposedObject = bp.getEarlyBeanReference(exposedObject, beanName); } } return exposedObject; }