spring作为Java世界应用最广泛的开源框架,能极大降低企业应用开发的复杂性,已经成为Java世界事实上的工业标准。作为一名Java开发者,在数年的spring的使用过程中,我愈发感觉对于spring提供的功能,不仅要知其然,还要知其所以然。因此我开始研究spring的源码,研究其功能是如何实现的。研究其他框架,例如mybatis,dubbo等等是如何介入到spring里工作的。掌握这些对于我们平时解决问题有很大帮助,因为现在spring提供了越来越多的新特性,如自动配置,环境profile等等,越来越多的东西被隐藏在了幕后。
本文章就探讨下spring的最重要的生命周期是怎样的,这里我们要明白一个重要的点,就是每当spring创建并初始化出一个重要的类对象时,就会提供有相应的扩展点供我们定制修改,这个是非常重要的,这样我们才能介入到spring里实现我们自己的东西。这里也体现了一个重要的设计模式:开闭原则,即对扩展开放,对修改关闭。
举几个例子:
spring的xml配置文件里bean的配置信息我们一般不直接赋值,而是统一收集写在properties文件里,由spring在启动时实现替换,像这样(dispatcher-servlet.xml):
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop">
<context:property-placeholder ignore-unresolvable="true" location="classpath:application.properties"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="${web.view.prefix}"/>
<property name="suffix" value="${web.view.suffix}"/>
</bean>
</beans>
application.properties文件:
web.view.prefix=/WEB-INF/views/
web.view.suffix=.jsp
那么spring是如何实现替换的呢?
再举一个例子,阿里的dubbo是一款高性能、轻量级的开源Java RPC框架,在spring里使用dubbo是非常简单的。
服务提供者(加上dubbo的Service注解即会将其变成远程服务):
@Service(version = "1.0.0")
public class UserDubboServiceImpl implements UserDubboService {
@Override
public UserBaseDto getByUsername(String username) {
// ......
}
}
服务消费者(加上dubbo的Reference注解即可引入远程服务):
@Component
public class DubboTest {
@Reference(version = "1.0.0")
private UserDubboService userDubboService;
@Test
public void test() {
System.out.println(userDubboService.getByUsername("sysadmin"));
}
}
那么dubbo又是怎么介入到spring里起作用的呢?
为了解答这些问题,我从spring的源码开始一一分析。话不多说,我们先来建立一个普通的使用maven管理的Java web应用,目录结构如下:
其中web.xml的内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<context-param>
<!-- 使用globalInitializerClasses或者contextInitializerClasses其实效果是一样的 -->
<param-name>globalInitializerClasses</param-name>
<param-value>org.javamaster.spring.lifecycle.initializers.LifecycleApplicationContextInitializer</param-value>
</context-param>
<!--
ContextLoaderListener首先执行, 建立第一个应用上下文ApplicationContext,
搜索bean的范围为applicationContext.xml, applicationContext.xml定义的
bean均会被纳入到此应用上下文ApplicationContext中管理
-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--
当ContextLoaderListener执行完, DispatcherServlet开始执行, 建立第二个应用上下文ApplicationContext,
搜索bean的范围为dispatcher-servlet.xml, dispatcher-servlet.xml定义的bean均会被纳入到此应用上下文
ApplicationContext中管理, 注意也包括component-scan能扫描到的所有bean
另外, 此应用上下文ApplicationContext的parent会被设置为ContextLoaderListener建立的第一个应用上下文ApplicationContext
-->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>applicationName</param-name>
<param-value>spring-lifecycle</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
当我们启动应用时,spring的奇妙旅程就从ContextLoaderListener开始了(只保留关键代码):
public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
// ......
@Override
public void contextInitialized(ServletContextEvent event) {
initWebApplicationContext(event.getServletContext());
}
// ......
}
调试跟踪方法的执行流程,找到了spring的第一个扩展点,实现了ApplicationContextInitializer接口的类会被调用执行(只保留关键代码):
public class ContextLoader {
protected void customizeContext(ServletContext sc, ConfigurableWebApplicationContext wac) {
// 找到所有实现了ApplicationContextInitializer接口的类
List<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>> initializerClasses =
determineContextInitializerClasses(sc);
// ......
// 对找到的类进行排序
AnnotationAwareOrderComparator.sort(this.contextInitializers);
for (ApplicationContextInitializer<ConfigurableApplicationContext> initializer : this.contextInitializers) {
// 调用其initialize方法
initializer.initialize(wac);
}
}
}
可以看到initialize方法传入了ApplicationContext对象,以便于我们按需扩展。关于这里对找到的类进行排序的规则,spring引入两个排序相关的接口:
- PriorityOrdered是一等公民,首先被执行,PriorityOrdered公民之间通过接口返回值排序
- Ordered是二等公民,然后执行,Ordered公民之间通过接口返回值排序
- 都没有实现是三等公民,最后执行
这里讨论的规则基本也适用于下面说的其他spring接口。
继续往下走,来到refresh方法(只保留关键代码),基本上spring的所有关键逻辑都在这里了:
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.
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) {
// ......
}
// ......
}
}
}
继续跟踪方法执行,找到下个扩展点,实现了BeanDefinitionRegistryPostProcessor接口的类会被先执行,然后到实现了BeanFactoryPostProcessor接口的类被执行(只保留关键代码):
final class PostProcessorRegistrationDelegate {
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// ......
// 找到实现了BeanDefinitionRegistryPostProcessor的对象
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// ......
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 调用其postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// ......
// 找到实现了BeanFactoryPostProcessor的对象
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// ......
// 排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 调用其postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// ......
}
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}
}
实现这两个接口可以定制BeanDefinitionRegistry对象和ConfigurableListableBeanFactory对象。
接下来开始到bean的生命周期,继续调试执行,到createBean方法,找到下一个扩展点,实现了InstantiationAwareBeanPostProcessor接口的类的postProcessBeforeInstantiation方法会被执行(只保留关键代码):
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// ......
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
// ......
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
// ......
}
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
}
继续深入到doCreateBean方法,在bean new出来之后初始化之前,此时spring又提供了一个扩展点,实现MergedBeanDefinitionPostProcessor接口的类会被执行(只保留关键代码):
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// ......
// Allow post-processors to modify the merged bean definition.
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
// ......
}
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
}
实现这个接口可以定制RootBeanDefinition对象。
继续往下走,populateBean方法开始给bean属性赋值,赋值之前,实现了InstantiationAwareBeanPostProcessor接口的类的postProcessAfterInstantiation方法会被执行,接着是postProcessPropertyValues方法被调用(只保留关键代码):
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// ......
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
// ......
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
}
所以这个接口可用来定制PropertyValues对象以及bean自身。
继续往下执行,可以看到相关的Aware后缀的接口方法会被调用(只保留关键代码):
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
// ......
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
}
因此当我们的bean对象需要拿到spring的一些重要对象时,只要实现这些相关Aware后缀接口,就会在这里由spring将对象注入,例如实现BeanFactoryAware接口就可拿到BeanFactory对象。
再接着往下走,实现了BeanPostProcessor接口的类的postProcessBeforeInitialization方法会被执行(只保留关键代码):
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
// ......
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
}
值的一提的是这里的BeanPostProcessor接口的实现有两个spring提供的类ApplicationContextAwareProcessor和ServletContextAwareProcessor,其作用也是调用相关Aware后缀的接口方法,为bean注入对象,还有一个CommonAnnotationBeanPostProcessor类,用于支持Javax注解@PostConstruct和@PreDestroy(只保留关键代码):
class ApplicationContextAwareProcessor implements BeanPostProcessor {
// ......
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);
}
}
}
}
public class ServletContextAwareProcessor implements BeanPostProcessor {
// ......
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (getServletContext() != null && bean instanceof ServletContextAware) {
((ServletContextAware) bean).setServletContext(getServletContext());
}
if (getServletConfig() != null && bean instanceof ServletConfigAware) {
((ServletConfigAware) bean).setServletConfig(getServletConfig());
}
return bean;
}
}
public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {
// ......
public CommonAnnotationBeanPostProcessor() {
setOrder(Ordered.LOWEST_PRECEDENCE - 3);
setInitAnnotationType(PostConstruct.class);
setDestroyAnnotationType(PreDestroy.class);
ignoreResourceType("javax.xml.ws.WebServiceContext");
}
// ......
}
可以看到,假如我们的bean实现了EnvironmentAware接口,那么就是在这里由spring注入Environment对象的。
假如bean的某个实例方法带有@PostConstruct,则此方法也会在此时被调用。
接着往下走,如果bean实现了InitializingBean或者带有initMethod方法,则会在此时调用(只保留关键代码):
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
// ......
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
// ......
((InitializingBean) bean).afterPropertiesSet();
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
// ......
invokeCustomInitMethod(beanName, bean, mbd);
// ......
}
}
protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd)
throws Throwable {
String initMethodName = mbd.getInitMethodName();
Assert.state(initMethodName != null, "No init method set");
final Method initMethod = (mbd.isNonPublicAccessAllowed() ?
BeanUtils.findMethod(bean.getClass(), initMethodName) :
ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
// ......
ReflectionUtils.makeAccessible(initMethod);
initMethod.invoke(bean);
// ......
}
}
最后,实现了BeanPostProcessor接口的类的postProcessAfterInitialization方法会被执行(只保留关键代码):
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
// ......
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// ......
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
// ......
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
}
至此bean基本已创建并初始化完成,其他的bean重复这个过程。当所有的bean都准备好时,spring就会发布一个ApplicationContext的Refresh完成事件,这时实现了ApplicationListener<ContextRefreshedEvent>接口的类的onApplicationEvent就会在这里被调用(只保留关键代码):
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
protected void finishRefresh() {
// ......
// Publish the final event.
publishEvent(new ContextRefreshedEvent(this));
// ......
}
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
// ......
// Decorate event as an ApplicationEvent if necessary
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent) event;
}
else {
applicationEvent = new PayloadApplicationEvent<>(this, event);
if (eventType == null) {
eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType();
}
}
// Multicast right now if possible - or lazily once the multicaster is initialized
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
}
else {
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
// Publish event via parent context as well...
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
}
else {
this.parent.publishEvent(event);
}
}
}
}
至此ContextLoaderListener执行完成。当应用关闭时,ContextLoaderListener的contextDestroyed方法会被容器调用:
public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent event) {
closeWebApplicationContext(event.getServletContext());
ContextCleanupListener.cleanupAttributes(event.getServletContext());
}
}
跟踪方法执行,会发现ApplicationContext的close方法被调用,此方法用于清理ApplicationContext的数据(只保留关键代码):
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
protected void doClose() {
// ......
publishEvent(new ContextClosedEvent(this))
// ......
// Destroy all cached singletons in the context's BeanFactory.
destroyBeans();
// Close the state of this context itself.
closeBeanFactory();
// Let subclasses do some final clean-up if they wish...
onClose();
this.active.set(false);
}
}
publishEvent方法发布一个应用关闭事件,这时实现了ApplicationListener<ContextClosedEvent>接口的类的onApplicationEvent就会在这里被调用。
接下来destroyBeans方法会检查bean的实例方法是否带有@PreDestroy注解,如果是,则此方法会被调用。其次查看bean是否实现了DisposableBean接口,如果是,则会调用其destroy方法,如果bean还定义了destroyMethod,则destroyMethod随后也会被调用。
以上就是spring的完整生命周期,总结:
ApplicationContextInitializer.initialize(ApplicationContext)
↓
BeanDefinitionRegistryPostProcessor
.postProcessBeanDefinitionRegistry(BeanDefinitionRegistry)
↓
BeanDefinitionRegistryPostProcessor
.postProcessBeanFactory(ConfigurableListableBeanFactory)
↓
BeanFactoryPostProcessor.postProcessBeanFactory(ConfigurableListableBeanFactory)
↓
bean的生命周期开始:
InstantiationAwareBeanPostProcessor
.postProcessBeforeInstantiation(Class<?>, String)
↓
MergedBeanDefinitionPostProcessor
.postProcessMergedBeanDefinition(RootBeanDefinition, Class<?>, String)
↓
InstantiationAwareBeanPostProcessor
.postProcessAfterInstantiation(Object, String)
↓
InstantiationAwareBeanPostProcessor
.postProcessPropertyValues(PropertyValues, PropertyDescriptor[], Object, String)
↓
BeanNameAware.setBeanName(String)
↓
BeanClassLoaderAware.setBeanClassLoader(ClassLoader)
↓
BeanFactoryAware.setBeanFactory(BeanFactory)
↓
BeanPostProcessor.postProcessBeforeInitialization(Object, String)
↓
EnvironmentAware.setEnvironment(Environment)
↓
EmbeddedValueResolverAware.setEmbeddedValueResolver(StringValueResolver)
↓
ResourceLoaderAware.setResourceLoader(ResourceLoader)
↓
ApplicationEventPublisherAware
.setApplicationEventPublisher(ApplicationEventPublisher)
↓
MessageSourceAware.setMessageSource(MessageSource)
↓
ApplicationContextAware.setApplicationContext(ApplicationContext)
↓
ServletContextAware.setServletContext(ServletContext)
↓
ServletConfigAware.setServletConfig(ServletConfig)
↓
@PostConstruct
↓
InitializingBean.afterPropertiesSet()
↓
initMethod()
↓
BeanPostProcessor.postProcessAfterInitialization(Object,String)
bean初始化完成,其余bean重复这个过程
所有bean初始化完成
↓
ApplicationListener<ContextRefreshEvent>.onApplicationEvent(ContextRefreshEvent)
上下文初始化完成
当应用关闭时
↓
ApplicationListener<ContextClosedEvent>.onApplicationEvent(ContextClosedEvent)
↓
@PreDestroy
↓
DisposableBean.destroy()
↓
destroyMethod()
另外,我们这个是Web应用,也配了DispatcherServlet,所以前面那里当ContextLoaderListener执行完时,就会开始初始化DispatcherServlet,建立Web应用上下文ApplicationContext,初始化从init方法开始(只保留关键代码):
public abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware {
@Override
public final void init() throws ServletException {
// ......
// Let subclasses do whatever initialization they like.
initServletBean();
// ......
}
@Override
protected final void initServletBean() throws ServletException {
// ......
this.webApplicationContext = initWebApplicationContext();
initFrameworkServlet();
// ......
}
protected WebApplicationContext initWebApplicationContext() {
WebApplicationContext rootContext =
WebApplicationContextUtils.getWebApplicationContext(getServletContext());
WebApplicationContext wac = null;
// ......
// No context instance is defined for this servlet -> create a local one
wac = createWebApplicationContext(rootContext);
// ......
}
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) {
// ......
wac.setServletContext(getServletContext());
wac.setServletConfig(getServletConfig());
wac.setNamespace(getNamespace());
wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener()));
// The wac environment's #initPropertySources will be called in any case when the context
// is refreshed; do it eagerly here to ensure servlet property sources are in place for
// use in any post-processing or initialization that occurs below prior to #refresh
ConfigurableEnvironment env = wac.getEnvironment();
if (env instanceof ConfigurableWebEnvironment) {
((ConfigurableWebEnvironment) env).initPropertySources(getServletContext(), getServletConfig());
}
postProcessWebApplicationContext(wac);
applyInitializers(wac);
wac.refresh();
}
}
这里建立应用上下文ApplicationContext同ContextLoaderListener一样。
熟悉了spring 的生命周期后,前面那两个问题就可以看源码回答了:
第一个:属性替换的是如何实现的。当我们在xml配置文件中配了这一行:
<context:property-placeholder ignore-unresolvable="true" location="classpath:application.properties"/>
就会有一个PropertySourcesPlaceholderConfigurer的类在其作用,观察这个类,它实现了BeanFactoryPostProcessor接口以及相关Aware接口:
public class PropertySourcesPlaceholderConfigurer extends PlaceholderConfigurerSupport implements EnvironmentAware {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// ......
// 实现了属性替换
processProperties(beanFactory, new PropertySourcesPropertyResolver(this.propertySources));
this.appliedPropertySources = this.propertySources;
}
}
processProperties方法最终实现了属性替换,详细我就不展开分析了,有兴趣的同学可以去研究。
第二个:dubbo如何加入spring里的。一样,翻其源码,可以看到是这个类完成这个工作的:
public class AnnotationBean extends AbstractConfig implements DisposableBean, BeanFactoryPostProcessor, BeanPostProcessor, ApplicationContextAware {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
// ......
// 判断bean是否带有dubbo的Service注解,有则特殊处理
Service service = bean.getClass().getAnnotation(Service.class);
if (service != null) {
ServiceBean<Object> serviceConfig = new ServiceBean<Object>(service);
serviceConfig.setRef(bean);
// ......
}
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
// ......
// 判断bean是否带有dubbo的Reference注解,有则特殊处理
Reference reference = field.getAnnotation(Reference.class);
if (reference != null) {
Object value = refer(reference, field.getType());
if (value != null) {
field.set(bean, value);
}
}
// ......
}
}
此类也是通过实现BeanFactoryPostProcessor接口来做到介入spring里的。
github源码:
https://github.com/jufeng98/java-mastergithub.com