- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
Bean工厂实现应该尽可能支持标准Bean生命周期接口。整套初始化方法及其标准顺序如下:
BeanNameAware.setBeanName,
BeanClassLoaderAware.setBeanClassLoader,
BeanFactoryAware.setBeanFactory,
org.springframework.context.EnvironmentAware.setEnvironment,
org.springframework.context.EmbeddedValueResolverAware.setEmbeddedValueResolver,
org.springframework.context.ResourceLoaderAware.setResourceLoader,
org.springframework.context.ApplicationEventPublisherAware.setApplicationEventPublisher,org.springframework.context.MessageSourceAware.setMessageSource,
org.springframework.context.ApplicationContextAware.setApplicationContext,
org.springframework.web.context.ServletContextAware.setServletContext,
org.springframework.beans.factory.config.BeanPostProcessor.postProcessBeforeInitialization, // 实例化之前
InitializingBean.afterPropertiesSet, //实例化之后
org.springframework.beans.factory.support.RootBeanDefinition.getInitMethodName, // 初始化方法
org.springframework.beans.factory.config.BeanPostProcessor.postProcessAfterInitialization, // 初始化之后
org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor.postProcessBeforDestruction, // 关闭容器,销毁bean之前
DisposableBean.destroy,
org.springframework.beans.factory.support.RootBeanDefinition.getDestroyMethodName
从ClassPathXmlApplicationContext
的构造函数开始作为入口分析:
整个生命周期大致如图所示:
在obtainFreshBeanFactory
方法中先loadBeanDefinitions
加载bean定义,然后创建beanFactory
实例,以及其他一些系统必要组件的加载
BeanDefinitionRegistryPostProcessor
接口的postProcessBeanDefinitionRegistry
BeanFactoryPostProcessor
的postProcessBeanFactory
方法InstantiationAwareBeanPostProcessor
接口的postProcessBeforeInstantiation
前置方法bean
的机会,如果返回null,则开始正式创建beanpostProcessAfterInitialization
后置方法MergedBeanDefinitionPostProcessor
的postProcessMergedBeanDefinition
方法BeanNameAware
的setBeanName
方法BeanClassLoaderAware
的setBeanClassLoader
方法BeanFactoryAware
的setBeanFactory
方法BeanPostProcessor
的postProcessBeforeInitialization
前置方法InitializingBean
的afterPropertiesSet
方法BeanPostProcessor
的postProcessAfterInitialization
后置方法DestructionAwareBeanPostProcessor
的requiresDestruction
方法ApplicationContextAware
的setApplicationContext
方法xxAware
实现原理以ApplicationContextAware
为例:
其实还是利用BeanPostProcessor
的能力,关键代码如下:
class ApplicationContextAwareProcessor implements BeanPostProcessor {
@Override
@Nullable
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
return bean;
}
AccessControlContext acc = null;
if (System.getSecurityManager() != null) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
// 通过调用这个方法
invokeAwareInterfaces(bean);
}
return bean;
}
private void invokeAwareInterfaces(Object bean) {
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);
}
}
}
我正在开发一个使用多个 turtle 的滚动游戏。玩家 turtle 根据按键命令在 Y 轴上移动。当危害和好处在 X 轴上移动时,然后循环并改变 Y 轴位置。我尝试定义一个名为 colliding(
我不明白为什么他们不接受这个作为解决方案,他们说这是一个错误的答案:- #include int main(void) { int val=0; printf("Input:- \n
我正在使用基于表单的身份验证。 我有一个注销链接,如下所示: 以及对应的注销方法: public String logout() { FacesContext.getCurren
在 IIS7 应用程序池中有一个设置 Idle-time out 默认是 20 分钟,其中说: Amount of time(in minutes) a worker process will rem
我是一名优秀的程序员,十分优秀!