整个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)
这三个方法执行完了。后面的方法放到下一节。