赞
踩
面试过程中问得最多的可能是自动装配的原理,而自动装配是在启动过程中完成,只不过在刚开始的时候我们选择性的跳过了,下面详细讲解自动装配的过程。
-
- public ConfigurableApplicationContext run(String... args) {
- StopWatch stopWatch = new StopWatch();
- stopWatch.start();
- ConfigurableApplicationContext context = null;
- Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
- configureHeadlessProperty();
- SpringApplicationRunListeners listeners = getRunListeners(args);
- listeners.starting();
- try {
- ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
- ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
- configureIgnoreBeanInfo(environment);
- Banner printedBanner = printBanner(environment);
- context = createApplicationContext();
- exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
- new Class[] { ConfigurableApplicationContext.class }, context);
- //此处完成自动装配的过程
- prepareContext(context, environment, listeners, applicationArguments, printedBanner);
- refreshContext(context);
- afterRefresh(context, applicationArguments);
- stopWatch.stop();
- if (this.logStartupInfo) {
- new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
- }
- listeners.started(context);
- callRunners(context, applicationArguments);
- }
- catch (Throwable ex) {
- handleRunFailure(context, ex, exceptionReporters, listeners);
- throw new IllegalStateException(ex);
- }
-
- try {
- listeners.running(context);
- }
- catch (Throwable ex) {
- handleRunFailure(context, ex, exceptionReporters, null);
- throw new IllegalStateException(ex);
- }
- return context;
- }
-
-
- //prepareContext方法
- private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
- SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
- context.setEnvironment(environment);
- postProcessApplicationContext(context);
- applyInitializers(context);
- listeners.contextPrepared(context);
- if (this.logStartupInfo) {
- logStartupInfo(context.getParent() == null);
- logStartupProfileInfo(context);
- }
- // Add boot specific singleton beans
- ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
- beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
- if (printedBanner != null) {
- beanFactory.registerSingleton("springBootBanner", printedBanner);
- }
- if (beanFactory instanceof DefaultListableBeanFactory) {
- ((DefaultListableBeanFactory) beanFactory)
- .setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
- }
- if (this.lazyInitialization) {
- context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
- }
- // Load the sources
- Set<Object> sources = getAllSources();
- Assert.notEmpty(sources, "Sources must not be empty");
- //load方法完成该功能
- load(context, sources.toArray(new Object[0]));
- listeners.contextLoaded(context);
- }
-
- /**
- * Load beans into the application context.
- * @param context the context to load beans into
- * @param sources the sources to load
- * 加载bean对象到context中
- */
- protected void load(ApplicationContext context, Object[] sources) {
- if (logger.isDebugEnabled()) {
- logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources));
- }
- //获取bean对象定义的加载器
- 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();
- }
-
- /**
- * Load the sources into the reader.
- * @return the number of loaded beans
- */
- int load() {
- int count = 0;
- for (Object source : this.sources) {
- count += load(source);
- }
- return count;
- }
-
-
- //实际记载bean的方法
- private int load(Object source) {
- Assert.notNull(source, "Source must not be null");
- //如果是class类型,启用注解类型
- if (source instanceof Class<?>) {
- return load((Class<?>) source);
- }
- //如果是resource类型,启动xml解析
- if (source instanceof Resource) {
- return load((Resource) source);
- }
- //如果是package类型,启用扫描包,例如@ComponentScan
- if (source instanceof Package) {
- return load((Package) source);
- }
- //如果是字符串类型,直接加载
- if (source instanceof CharSequence) {
- return load((CharSequence) source);
- }
- throw new IllegalArgumentException("Invalid source type " + source.getClass());
- }
-
-
- private int load(Class<?> source) {
- //判断使用groovy脚本
- 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)) {
- this.annotatedReader.register(source);
- return 1;
- }
- return 0;
- }
-
-
- private b
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。