转载

Spring SmartInitializingSingleton 原 荐

OrangeJoke的个人空间 spring

正文

Spring SmartInitializingSingleton

Spring SmartInitializingSingleton 原 荐
  OrangeJoke 发布于 39分钟前

字数 619

阅读 2

收藏 0

面试:你懂什么是分布式系统吗?Redis分布式锁都不会?>>> Spring SmartInitializingSingleton 原 荐

使用场景

我们在这样的场景下使用,当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 {}

主要摘取上面一段说明来解答疑惑:

  1. 这个接口的功能类似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),对应性能也会更好一点。

  1. 文档里说到 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

OrangeJoke

粉丝 37

博文 54

码字总数 35975

作品 0

江北

高级程序员

提问

相关文章 最新文章

EventListener原理

目录 目录 流程 initApplicationEventMulticaster() registerListeners() finishRefresh() publishEvent() @EventListener处理 流程 容器的刷新流程如下: 其中与EventListener有关联的步骤 ......

4rnold

2018/08/12

0

0

聊聊spring cloud的AsyncLoadBalancerAutoConfiguration

序 本文主要研究一下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

序 本文主要研究一下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的继承关系和影响

前言 对于一个简单的Spring boot应用,它的spring context是只会有一个。 非web spring boot应用,context是 web spring boot应用,context是 是spring boot里自己实现的一个context,主要功...

横云断岭

2018/12/10

0

0

Spring Bean生命周期-finishBeanFactoryInitialization(九)

这个方法应该是ApplicationContext刷新的时候,最重要的方法了,因为所有的bean,如果不是lazy-init的都会在这一步进行实例化,并且做一些处理。 狭义上的Bean生命周期就在这一步进行完成,我...

Real_man

2018/10/12

0

0

没有更多内容

加载失败,请刷新页面

加载更多
深入搜索引擎原理

之前几段工作经历都与搜索有关,现在也有业务在用搜索,对搜索引擎做一个原理性的分享,包括搜索的一系列核心数据结构和算法,尽量覆盖搜索引擎的核心原理,但不涉及数据挖掘、NLP等。文章有...

阿里云云栖社区

10分钟前

2

0

Spring SmartInitializingSingleton 原 荐
k8s高可用架构

概述 地址sealos, 让kubernetes高可用不再需要keepalived haproxy和ansible,sealyun定制超级版kubeadm通过ipvs代理多个master,优雅解决k8s高可用问题。 环境介绍 iprole10.103.97.200m...

xiangyunyan

22分钟前

0

0

java 面试知识点笔记(四)垃圾回收

问:对象判定为垃圾的标准? 没有被其他对象引用 问:对象判定为垃圾的算法? 引用计数算法 通过判断对象的引用数量来判断对象是否可以被回收 每个对象实例都有一个引用计数器,被引用则+1,...

断风格男丶

31分钟前

0

0

Spring boot 注入失败

spring boot注入失败的场景主要有 Application类位置异常 待注入的类位于Application类所在包的外层; @ComponentScan扫描的位置没有包括待注入的bean的包 方法作用域问题 该问题我们在Contr...

哭哭吓唬你

32分钟前

0

0

Nginx的正则表达式

什么是正则表达式 正则表达式由一些普通字符和一些元字符(metacharacters)组成。普通字符包括大小写的字母和数字,而元字符则具有特殊的含义,我们下面会给予解释。 在最简单的情况下,一个...

果树啊

34分钟前

3

0

没有更多内容

加载失败,请刷新页面

加载更多
原文  https://my.oschina.net/tigerlene/blog/3049797
正文到此结束
Loading...