Spring SmartInitializingSingleton
原
荐
字数 619
阅读 2
收藏 0
面试:你懂什么是分布式系统吗?Redis分布式锁都不会?>>>
使用场景
我们在这样的场景下使用,当ApplicationContext 加载完所有的Bean之后,我们来做一些我们想要的操作。 下面是使用方法:
public class MyRegister implements SmartInitializingSingleton { Logger logger = LoggerFactory.getLogger(MyRegister.class); private final DefaultListableBeanFactory beanFactory; public MyRegister(DefaultListableBeanFactory beanFactory) { this.beanFactory = beanFactory; } @Override public void afterSingletonsInstantiated() { Map<String, Tiger> redisCacheProviderMap = beanFactory.getBeansOfType(Tiger.class); logger.info("tiger pre init"); } }
接口说明
/** *<p> Callback interface triggered at the end of the singleton pre-instantiation phase * during {@link BeanFactory} bootstrap. * * <p>This callback variant is somewhat similar to * {@link org.springframework.context.event.ContextRefreshedEvent} but doesn't * require an implementation of {@link org.springframework.context.ApplicationListener}, * with no need to filter context references across a context hierarchy etc. * It also implies a more minimal dependency on just the {@code beans} package * and is being honored by standalone {@link ListableBeanFactory} implementations, * not just in an {@link org.springframework.context.ApplicationContext} environment. */ public interface SmartInitializingSingleton {}
主要摘取上面一段说明来解答疑惑:
- 这个接口的功能类似ContextRefreshedEvent(由Configua>bleApplicationContext.refresh()触发),ContextRefreshedEvent的具体阶段来看下面具体文档。
Published when the ApplicationContext is initialized or refreshed (for example, by using the refresh() method on the ConfigurableApplicationContext interface). Here, “initialized” means that all beans are loaded, post-processor beans are detected and activated, singletons are pre-instantiated, and the ApplicationContext object is ready for use. As long as the context has not been closed, a refresh can be triggered multiple times, provided that the chosen ApplicationContext actually supports such “hot” refreshes. For example, XmlWebApplicationContext supports hot refreshes, but GenericApplicationContext does not.
对比接收事件的优点:就是不需要实现ApplicationListener,引用也更加简单(不需要获取ApplicationContext),对应性能也会更好一点。
- 文档里说到 pre-instantiation phase 这个比较疑惑,实际上这里的pre-instantiation对应SmartInitializingSingleton的执行过程·
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext, DisposableBean { public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 省略其他步骤......... // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } } finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { //省略其他步骤....... // Instantiate all remaining (non-lazy-init) singletons. beanFactory.preInstantiateSingletons(); }
所以结论就是SmartInitializingSingleton的方法就是在finishRefresh() 触发ContextRefreshedEvent事件前执行的。所以上面的pre-instantiation phase说的就是beanFactory.preInstantiateSingletons()这方法执行。
实现
beanFactory.preInstantiateSingletons();
// Trigger post-initialization callback for all applicable beans... for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { smartSingleton.afterSingletonsInstantiated(); return null; } }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } }
DefaultListableBeanFactory 这个类的实例是怎么构造注入的?构造函数注入。
另外的方法:Bean获取ApplicationContext是需要实现Aware接口的,类似这样:
//spring @EventListner 处理器 public class EventListenerMethodProcessor implements SmartInitializingSingleton, ApplicationContextAware { private ConfigurableApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { Assert.isTrue(applicationContext instanceof ConfigurableApplicationContext, "ApplicationContext does not implement ConfigurableApplicationContext"); this.applicationContext = (ConfigurableApplicationContext) applicationContext; }
© 著作权归作者所有
上一篇: Java Async IO Library: Quasar (use Fiber)
下一篇: spring boot deploy with javaagent
相关文章 最新文章
目录 目录 流程 initApplicationEventMulticaster() registerListeners() finishRefresh() publishEvent() @EventListener处理 流程 容器的刷新流程如下: 其中与EventListener有关联的步骤 ......
4rnold
2018/08/12
0
0
序 本文主要研究一下AsyncLoadBalancerAutoConfiguration AsyncLoadBalancerAutoConfiguration spring-cloud-commons-2.0.0.RELEASE-sources.jar!/org/springframework/cloud/client/loadba......
go4it
2018/07/17
0
0
序 本文主要研究一下spring cloud的LoadBalancerAutoConfiguration RibbonAutoConfiguration spring-cloud-netflix-ribbon-2.0.0.RC2-sources.jar!/org/springframework/cloud/netflix/ribb......
go4it
2018/07/16
0
0
前言 对于一个简单的Spring boot应用,它的spring context是只会有一个。 非web spring boot应用,context是 web spring boot应用,context是 是spring boot里自己实现的一个context,主要功...
横云断岭
2018/12/10
0
0
这个方法应该是ApplicationContext刷新的时候,最重要的方法了,因为所有的bean,如果不是lazy-init的都会在这一步进行实例化,并且做一些处理。 狭义上的Bean生命周期就在这一步进行完成,我...
Real_man
2018/10/12
0
0
没有更多内容
加载失败,请刷新页面
加载更多之前几段工作经历都与搜索有关,现在也有业务在用搜索,对搜索引擎做一个原理性的分享,包括搜索的一系列核心数据结构和算法,尽量覆盖搜索引擎的核心原理,但不涉及数据挖掘、NLP等。文章有...
阿里云云栖社区
10分钟前
2
0
概述 地址sealos, 让kubernetes高可用不再需要keepalived haproxy和ansible,sealyun定制超级版kubeadm通过ipvs代理多个master,优雅解决k8s高可用问题。 环境介绍 iprole10.103.97.200m...
xiangyunyan
22分钟前
0
0
问:对象判定为垃圾的标准? 没有被其他对象引用 问:对象判定为垃圾的算法? 引用计数算法 通过判断对象的引用数量来判断对象是否可以被回收 每个对象实例都有一个引用计数器,被引用则+1,...
断风格男丶
31分钟前
0
0
spring boot注入失败的场景主要有 Application类位置异常 待注入的类位于Application类所在包的外层; @ComponentScan扫描的位置没有包括待注入的bean的包 方法作用域问题 该问题我们在Contr...
哭哭吓唬你
32分钟前
0
0
什么是正则表达式 正则表达式由一些普通字符和一些元字符(metacharacters)组成。普通字符包括大小写的字母和数字,而元字符则具有特殊的含义,我们下面会给予解释。 在最简单的情况下,一个...
果树啊
34分钟前
3
0
没有更多内容
加载失败,请刷新页面
加载更多以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。