简介
spring容器中Bean的生命周期内所有可扩展的点的调用顺序扩展接口 | 实现接口 |
---|---|
ApplicationContextlnitializer | initialize |
AbstractApplicationContext | refreshe |
BeanDefinitionRegistryPostProcessor | postProcessBeanDefinitionRegistry |
BeanDefinitionRegistryPostProcessor | postProcessBeanFactory |
BeanFactoryPostProcessor | postProcessBeanFactory |
instantiationAwareBeanPostProcessor | postProcessBeforelnstantiation |
SmartlnstantiationAwareBeanPostProcessor | determineCandidateConstructors |
MergedBeanDefinitionPostProcessor | postProcessMergedBeanDefinition |
InstantiationAwareBeanPostProcessor | postProcessAfterlnstantiation |
SmartInstantiationAwareBeanPostProcessor | getEarlyBeanReference |
BeanNameAware | setBeanName |
BeanFactoryAware | postProcessPropertyValues |
ApplicationContextAwareProcessor | invokeAwarelnterfaces |
InstantiationAwareBeanPostProcessor | postProcessBeforelnstantiation |
@PostConstruct | |
InitializingBean | afterPropertiesSet |
FactoryBean | getobject |
SmartlnitializingSingleton | afterSingletonslnstantiated |
CommandLineRunner | run |
DisposableBean | destroy |
BeanNameAware是 Spring 框架的一个核心接口,主要的用途就是可以获取bean的名称,其触发点在Bean后处理器的BeforeInitialization方法之前,实现BeanNameAware接口的对象会在Spring容器中被自动注入Bean的名称。
/**
* 由希望知道其在 bean 工厂中名称的 beans 实现的接口。
* 注意通常不推荐一个对象依赖于其 bean 名称,因为这可能导致对外部配置的脆弱依赖,
* 以及可能的不必要的对 Spring API 的依赖。
*
* 有关所有 bean 生命周期方法的列表,请参见
* BeanFactory BeanFactory javadocs。
*
* @author Juergen Hoeller
* @author Chris Beams
* @since 01.11.2003
* @see BeanClassLoaderAware
* @see BeanFactoryAware
* @see InitializingBean
*/
public interface BeanNameAware extends Aware {
/**
* 设置在创建此 bean 的 bean 工厂中的 bean 的名称。
* 此方法在填充常规 bean 属性之后被调用,但在如 InitializingBean#afterPropertiesSet() 这样的
* 初始化回调或自定义初始化方法之前被调用。
* @param name 工厂中的 bean 的名称。注意,这个名称是工厂中使用的实际 bean 名称,
* 这可能与最初指定的名称不同:尤其对于内部 bean 名称,实际的 bean 名称可能已通过添加 "#..." 后缀变得唯一。
* 如果需要,可以使用 BeanFactoryUtils#originalBeanName(String) 方法来提取没有后缀的原始 bean 名称。
*/
void setBeanName(String name);
}
源码分析
源码路径org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory,这里的源码内容就不展开说了
private void invokeAwareMethods(String beanName, 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);
}
}
}
示例代码
示例一
beanName属性表示在Spring容器中注册的bean id,在我们的实现中,只是显示bean名称。
@Slf4j
@Configuration
public class ExtendBeanNameAware implements BeanNameAware {
@Override
public void setBeanName(String name) {
log.info("ExtendBeanNameAware---beanName:{}",name);
}
}
@Configuration
public class AppConfig {
@Bean(name = "hahahahahahaha")
public ExtendBeanNameAware testExtendBeanNameAware() {
ExtendBeanNameAware nameAware = new ExtendBeanNameAware();
return nameAware;
}
}
运行示例一
示例二
MyBaseStockService是一个抽象类,结合了 Spring 的三个特殊接口:BeanNameAware(让 Bean 知道其名字)、InitializingBean(Bean 属性设置后的初始化操作)和 DisposableBean(Bean 销毁前的操作)。
public class MyBaseStockService implements BeanNameAware, InitializingBean, DisposableBean {
private String beanName;
@Override
public void setBeanName(String beanName) {
this.beanName = beanName;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Stock " + beanName + " has been registered.");
}
@Override
public void destroy() throws Exception {
System.out.println("Stock " + beanName + " has been unregistered.");
}
}
MyStock300122 和 MyStock600100是两个股票类,都继承自 MyBaseStockService,因此它们会自动获得与 Spring 容器生命周期相关的基本功能。这种设计方式为多个支付服务提供了一个共同的生命周期管理模式,同时允许每个服务添加其特定的支付逻辑。
@Service
public class MyStock600100 extends MyBaseStockService {
}
@Service
public class MyStock300122 extends MyBaseStockService {
}
运行示例二
运行结果发现,当 Spring 容器启动并初始化 Beans 时,它正确地识别并实例化了 MyStock600100 和 MyStock300122 这两个服务。由于这两个服务都继承自 MyBaseStockService ,在 Bean 的属性被设置之后(即在 afterPropertiesSet() 方法中),它们分别打印出了 “Stock MyStock600100 has been registered.” 和 “Stock MyStock300122 has been registered.” 这两条信息,提供了一个共同的生命周期管理模式。
服务开启时
服务关闭时