Spring扩展点系列-BeanNameAware

简介

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
DisposableBeandestroy

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.” 这两条信息,提供了一个共同的生命周期管理模式。

服务开启时
在这里插入图片描述
服务关闭时
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值