spring生命周期
spring生命周期可以分为四大块
- 初始化
- 属性赋值
- 实例化bean(Aware接口,bean前置处理,初始化方法,bean后置处理)
- 销毁
如图所示
分析源码
让我们从doCreateBean这个方法,来了解spring的生命周期
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
return exposedObject;
初始化
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
aware接口
BeanFactory容器下
[在BeanFactory容器下] 检查Aware使用的是invokeAwareMethods(beanName, bean) 方法,点入之后我们可以看到
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);
}
}
}
若 Spring 检测到 bean 实现了 Aware 接口,则会为其注入相应的依赖。所以通过让bean 实现 Aware 接口,则能在 bean 中获得相应的 Spring 容器资源。 Spring 中提供的 Aware 接口有:
- BeanNameAware:注入当前 bean 对应 beanName;
- BeanClassLoaderAware:注入加载当前 bean 的 ClassLoader;
- BeanFactoryAware:注入 当前BeanFactory容器 的引用。
ApplicationContext容器下
[在ApplicationContext容器下],使用invokeAwareInterfaces 方法
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);
}
}
}
- EnvironmentAware:注入 Enviroment,一般用于获取配置属性;
- EmbeddedValueResolverAware:注入 EmbeddedValueResolver(Spring EL解析器),一般用于参数解析;
- ResourceLoaderAware:获取资源加载器,可以获得外部资源文件
- ApplicationEventPublisherAware: 事件发布器的接口
- ApplicationContextAware(ResourceLoader、ApplicationEventPublisherAware、MessageSourceAware):注入 - - —ApplicationContext 容器本身
Bean后置处理器
bean后置处理器使用applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName) 方法
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 处理
BeanFactory 和ApplicationContext的区别
BeanFactory
- BeanFactory是spring最底层的接口,只提供了获取bean的简单方法
ApplicationContext
- ApplicationContext是Spring容器上下文,他继承了Beanfactory并且还提供了其他多种功能。
-
国际化(MessageSource) -
访问资源,如URL和文件(ResourceLoader) -
载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层 -
消息发送、响应机制(ApplicationEventPublisher) -
AOP(拦截器)
常用接口 、
CommandLineRunner接口
主要用于实现在应用初始化后,去执行一段代码块逻辑,这段初始化代码在整个应用生命周期内只会执行一次。
@Component
public class ApplicationStartupRunner implements CommandLineRunner {
protected final Log logger = LogFactory.getLog(getClass());
@Override
public void run(String... args) throws Exception {
logger.info("ApplicationStartupRunner run method Started !!");
}
}
ApplicationContextAware接口
容器启动后,可以用来获取ApplicationContext上下文的情况
参考文献
|