文章目录
简介
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 |
BeanFactoryAware用于注入BeanFactory对象。我们可以访问创建该对象的BeanFactory 。借助 setBeanFactory()方法,我们将IoC 容器中的BeanFactory引用分配给beanFactory 属性,之后,我们可以创建函数直接使用它。
BeanNameAware的常用场景一般是用于日志记录。
源码分析
BeanFactoryAware是Aware的超级子接口
从源码中可以看到BeanFactoryAware只提供了一个set方法,该接口中只定义了setBeanFactory一个方法。
public interface BeanFactoryAware extends Aware {
void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
实现了Spring的Aware接口族的Beans(如BeanNameAware, BeanFactoryAware等)。如果提供的bean实现了任何这些接口,该方法会回调相应的Aware方法
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
当一个 bean 实现了如 BeanNameAware、BeanClassLoaderAware 或 BeanFactoryAware 等接口时,此方法确保正确的回调方法被调用,从而为 bean 提供关于其运行环境或其他相关信息。
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);
}
}
}
示例代码
示例一:验证BeanFactoryAware执行顺序
这里创建一个类去实现BeanFactoryAware,顺带也实现 BanNameAware接口,这样可以比对看出两者的执行顺序
@Slf4j
@Component
public class ExtendBeanFactoryAware implements BeanNameAware, BeanFactoryAware {
@Override
public void setBeanName(String name) {
log.info("ExtendBeanNameAware-2--beanName:{}",name);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
log.info("ExtendBeanFactoryAware-3--beanName:{}",beanFactory);
}
}
注:如果把@Component缓存@Configuration,setBeanFactory会执行两次。setBeanFactory-》setBeanName=》setBeanFactory
运行示例
示例二:动态获取其他bean
下面这个示例主要展示一个常用的场景,一个 Bean 可以在运行时动态获取其他 Bean
@Slf4j
@Component
public class ExtendBeanFactoryAware implements BeanNameAware, BeanFactoryAware {
private BeanFactory beanFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
log.info("ExtendBeanFactoryAware-3--beanName:{}",beanFactory);
}
public void getOtherBean() {
OtherBean otherBean = beanFactory.getBean(OtherBean.class);
System.out.println("获取 otherBean 实例: " + otherBean);
}
}
@Component
public class OtherBean {
@Override
public String toString() {
return "这是 OtherBean 实例";
}
}
@Configuration
public class AppConfig {
@Bean
public OtherBean getOtherBean () {
return new OtherBean();
}
@Bean
public ExtendBeanFactoryAware getExtendBeanFactoryAware () {
return new ExtendBeanFactoryAware();
}
}
//controller运行调用获取bean
@GetMapping("/getOtherBean")
public void getOtherBean() throws Exception{
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
ExtendBeanFactoryAware beanFactoryAware = context.getBean(ExtendBeanFactoryAware.class);
beanFactoryAware.getOtherBean();
}
运行示例
示例三:动态bean的状态
在运行时,可以通过 BeanFactoryAware检查某个 Bean 是否存在或者其状态,下面是代码展示
@Slf4j
@Component
public class ExtendBeanFactoryAware implements BeanNameAware, BeanFactoryAware {
private BeanFactory beanFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
log.info("ExtendBeanFactoryAware-3--beanName:{}",beanFactory);
}
public void checkBeanState() {
boolean exists = beanFactory.containsBean("getOtherBean");
log.info("otherBean 是否存在: {}" , exists);
}
}
@Component
public class OtherBean {
}
@Configuration
public class AppConfig {
//如果不指定Bean名,则默认是bean的名字为方法名
@Bean
public OtherBean getOtherBean () {
return new OtherBean();
}
@Bean
public ExtendBeanFactoryAware getExtendBeanFactoryAware () {
return new ExtendBeanFactoryAware();
}
}
//controller运行调用获取bean
@GetMapping("/checkBeanState")
public void checkBeanState() throws Exception{
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
ExtendBeanFactoryAware beanFactoryAware = context.getBean(ExtendBeanFactoryAware.class);
beanFactoryAware.checkBeanState();
}
运行示例