①、Spring AnnotationConfigApplicationContext 源码分析(3) ---->refresh() 大概结构;

整个spring 框架最重要的部分就是这个方法了。

这里先讲前面三个方法,后面的方法比较重要的都分开来单独讲。

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.

			/**
			 * 准备工作:
			 * 设置启动时间、是否激活标识位
			 * 初始化属性源(property source)配置
			 */
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			/**
			 * 告诉子类刷新内部bean工厂
			 * 拿到DefaultListableBeanFactory,供后面方法调用
			 */
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			/**
			 * 准备bean工厂
			 */
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				/**
				 * 这个方法在当前版本没有实现
				 * 可能在spring后面的版本会去扩展
				 */
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				/**
				 * 在上下文中调用注册为bean的工厂处理器
				 *
				 * 添加BeanPostProcessor
				 * 如果发现loadTimeWeaver的Bean
				 */
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				/**
				 * 注册BeanPostProcessor
				 * 自定义以及spring内部的
				 */
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				/**
				 * 国际化支持,不关心
				 */
				initMessageSource();

				// Initialize event multicaster for this context.
				/**
				 * 初始化事件监听多路广播器
				 */
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				/**
				 * 这个方法在springboot 使用内嵌tomcat等容器的时候使用;
				 * 在单独使用spring的时候就是个空方法
				 */
				onRefresh();

				// Check for listener beans and register them.
				/**
				 * 注册监听器
				 */
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				/**
				 * 实例化所有bean
				 */
				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()方法如下:

	/**
	 * 准备工作
	 */
	protected void prepareRefresh() {
		//记录初始化开始时间
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);	//context是否关闭的标志,设置为false
		this.active.set(true);	//context是否激活的标志,设置为true
 
		if (logger.isDebugEnabled()) {	//记录日志
			if (logger.isTraceEnabled()) {
				logger.trace("Refreshing " + this);
			}
			else {
				logger.debug("Refreshing " + getDisplayName());
			}
		}
 
		//留给子类实现的空方法
		initPropertySources();
 
		 /** AbstractPropertyResolver类的requiredProperties是个集合,
		  * 在下面的validateRequiredProperties方法中,都要拿requiredProperties中的元素作为key去检查是否存在对应的环境变量,
		  * 如果不存在就抛出异常
		  */
		getEnvironment().validateRequiredProperties();
 
		// 初始化earlyApplicationListeners容器 --LinkedHashSet
		if (this.earlyApplicationListeners == null) {
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
			// 清空applicationListeners容器  并将earlyApplicationListeners中的数据全部添加进来
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}
 
		// 初始化earlyApplicationEvents容器  --LinkedHashSet
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

②、obtainFreshBeanFactory()方法如下所示:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
	//往beanFactory中设置Id值,下面会说
	refreshBeanFactory();
	//返回当前BeanFactory.
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	if (logger.isDebugEnabled()) {
		logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
	}
	return beanFactory;
}

refreshBeanFactory()方法作用是设置beanFactory中的id ,id值大概为:
        org.springframework.context.annotation.AnnotationConfigApplicationContext@19dfb72a
如下所示:

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");
	}
	//往beanFactory中设置Id值,
	this.beanFactory.setSerializationId(getId());
}
==========================
public String getId() {
	return this.id;
}
==========================
private String id = ObjectUtils.identityToString(this);
==========================ObjectUtils.java======
public static String identityToString(Object obj) {
	if (obj == null) {
		return EMPTY_STRING;
	}
	return obj.getClass().getName() + "@" + getIdentityHexString(obj);
}

③、prepareBeanFactory(beanFactory);
            这个方法的作用是配置工厂的标准上下文特征,比如上下文的类加载器和后置处理器。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	beanFactory.setBeanClassLoader(getClassLoader());
	
	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 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 (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());
	}
}

这上面设置beanFactory的方法写的清晰明了了

a、设置BeanClassLoader,前面this()的时候已经赋值过了,这里应该是别的环境下可能需要赋值

beanFactory.setBeanClassLoader(getClassLoader());

b、添加bean表达式解释器StandardBeanExpressionResolver,为了能够让我们的beanFactory去解析bean表达式
      模板默认以前缀“#{”开头,以后缀“}”结尾
      可以修改默认额前缀后缀


      通过beanFactory.getBeanExpressionResolver()获得BeanExpressionResolver


     然后resolver.setExpressionPrefix(“%{”);resolver.setExpressionSuffix(“}”);

      
      那么什么时候用到这个解析器?

      就是在Bean进行初始化后会有属性填充的一步,方法如下:
      protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
              //属性填充
             applyPropertyValues(beanName, mbd, bw, pvs);
      }
      最终会通过AbstractBeanFactory中的evaluateBeanDefinitionString方法进行解析
      然后这时候就进到StandardBeanExpressionResolver中的evaluate方法中进行解析了

beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));

c、添加属性编辑器(暂时先不管)

beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

d、添加ApplicationContextAwareProcessor后置处理器
     该后置处理器的作用是找到那些实现了Aware接口的对象,
     赋值相应的方法,postProcessBeforeInitialization一定会调用invokeAwareInterfaces(),方法如下,
     这也是为什么那些类实现了ApplicationContextAware等Aware接口之后可以获取到相应的对象的原因。

beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
private void invokeAwareInterfaces(Object bean) {
	if (bean instanceof Aware) {
		if (bean instanceof EnvironmentAware) {
			((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
		}
		if (bean instanceof EmbeddedValueResolverAware) {
			((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
		}
		if (bean instanceof ResourceLoaderAware) {
			((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
		}
		if (bean instanceof ApplicationEventPublisherAware) {
			((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
		}
		if (bean instanceof MessageSourceAware) {
			((MessageSourceAware) bean).setMessageSource(this.applicationContext);
		}
		if (bean instanceof ApplicationContextAware) {
			((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
		}
	}
}

e、把这6个类添加到beanFactory的ignoredDependencyInterfaces中。 跳过以下属性的自动注入
     因为在ApplicationContextAwareProcessor后置处理器中通过setter注入

beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

至此,ignoredDependencyInterfaces已经添加到9个。
在这里插入图片描述

f、注册几个自动装配相关的类和实例
     添加到beanFactory中的resolvableDependencies中。
     在应用代码就可以通过类型自动装配把工厂实例和ApplicationContext实例设置到自定义bean的属性中
     
     例如:这几个属性都会被自动设置,虽然没有在显示的在bean定义xml中注入它们,或者在这几个接口的实体类中添加@Componet,同样也能够在我们需要的bean类中通过@Autowire或者@Resource获取

     @Autowire
     private BeanFactory beanFactory;
     @Autowire
     private ResourceLoader resourceLoader;
     @Autowire
     private ApplicationEventPublisher appEventPublisher;
     @Autowire
     private ApplicationContext appContext;

beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);

在这里插入图片描述

g、添加后置处理器,在bean初始化完成后判断是不是继承了ApplicationListener的监听器,是的话将它注册到应用的事件多播器上。

beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
public Object postProcessAfterInitialization(Object bean, String beanName) {
	if (this.applicationContext != null && bean instanceof ApplicationListener) {
		// potentially not detected as a listener by getBeanNamesForType retrieval
		Boolean flag = this.singletonNames.get(beanName);
		if (Boolean.TRUE.equals(flag)) {
			// singleton bean (top-level or inner): register on the fly
			this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
		}
		else if (Boolean.FALSE.equals(flag)) {
			if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
				// inner bean with other scope - can't reliably process events
				logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
						"but is not reachable for event multicasting by its containing ApplicationContext " +
						"because it does not have singleton scope. Only top-level listener beans are allowed " +
						"to be of non-singleton scope.");
			}
			this.singletonNames.remove(beanName);
		}
	}
	return bean;
}

上面this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);的代码如下。在多播器章节上再细说。

public void addApplicationListener(ApplicationListener<?> listener) {
	Assert.notNull(listener, "ApplicationListener must not be null");
	if (this.applicationEventMulticaster != null) {
		this.applicationEventMulticaster.addApplicationListener(listener);
	}
	else {
		this.applicationListeners.add(listener);
	}
}

h、添加系统的配置信息类到beanFactory的singletonObjects,对象里,添加到这个集合里面的对象就是最终的对象,
     这里涉及到三级缓存的问题,在获取bean章节再细说,这里只需要知道singletonObjects里add进了这三个对象。

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());
}

执行后看看beanFactory 的singletonObjects
在这里插入图片描述

至此refresh()方法的
prepareRefresh()、
obtainFreshBeanFactory()、
prepareBeanFactory(beanFactory)
这三个方法执行完了。后面的方法放到下一节。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值