首页 > 其他分享 >Spring扩展点系列-BeanFactoryAware

Spring扩展点系列-BeanFactoryAware

时间:2024-09-14 18:21:07浏览次数:11  
标签:beanFactory ExtendBeanFactoryAware Spring beanName 扩展 BeanFactoryAware bean publ

文章目录

简介

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

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();
}

运行示例
在这里插入图片描述

标签:beanFactory,ExtendBeanFactoryAware,Spring,beanName,扩展,BeanFactoryAware,bean,publ
From: https://blog.csdn.net/qq_32590535/article/details/142210400

相关文章

  • Springboot防疫物资管理系统yx5k5--(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、研究背景与意义随着全球公共卫生事件的频发,防疫物资的有效管理成为保障社会安全与稳定的关键环节。传统的手工管理模式已难以满足大规模、高效......
  • Springboot二手物品交易系统03374--(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、研究背景随着互联网技术的飞速发展和人们消费观念的转变,二手物品交易逐渐成为一种流行的消费模式。传统的二手市场存在信息不对称、交易效率低......
  • Springboot二手交易平台8h0k9程序+源码+数据库+调试部署+开发环境
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、项目背景在消费主义盛行的今天,商品更新换代速度加快,大量二手物品随之产生。为了促进资源的有效利用和循环利用,减少浪费,构建一个便捷、安全、高......
  • JAVA毕业设计171—基于Java+Springboot+vue3+小程序的宠物店小程序系统(源代码+数据库
    毕设所有选题:https://blog.csdn.net/2303_76227485/article/details/131104075基于Java+Springboot+vue3+小程序的宠物店小程序系统(源代码+数据库)171一、系统介绍本项目前后端分离(可以改为ssm版本),分为用户、店员、管理员三种角色1、用户:注册、登录、宠物购买(评论......
  • java springboot监听事件和处理事件
    在SpringBoot中,监听和处理事件是一种常用的模式,用于在应用程序的不同部分之间传递信息。Spring的事件发布/订阅模型允许我们创建自定义事件,并在这些事件发生时由注册的监听器进行处理。这里,我将提供一个简单的SpringBoot应用程序示例,其中将包括事件的定义、事件的发布以及事......
  • JAVA毕业设计174—基于Java+Springboot+vue3+小程序的农产品社区团购小程序系统(源代
    毕设所有选题:https://blog.csdn.net/2303_76227485/article/details/131104075基于Java+Springboot+vue3+小程序的农产品社区团购小程序系统(源代码+数据库+开题+万字论文)174一、系统介绍本项目前后端分离(可以改为ssm版本),分为用户、管理员两种角色1、用户:注册、登......
  • SpringBoot框架下的房产销售系统设计与实现
    摘要随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于房产销售系统当然也不能排除在外,随着网络技术的不断成熟,带动了房产销售系统,它彻底改变了过去传统的管理方式,不仅使服务管理难度变低了,还提升了管理的灵活性。这种个性化的平......
  • 房产销售系统开发:SpringBoot技术要点
    摘要随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于房产销售系统当然也不能排除在外,随着网络技术的不断成熟,带动了房产销售系统,它彻底改变了过去传统的管理方式,不仅使服务管理难度变低了,还提升了管理的灵活性。这种个性化的平......
  • 基于Java实现的漫画之家系统设计与实现(SpringBoot+Vue+MySQL+Tomcat)
    文章目录1.前言2.详细视频演示3.论文参考4.项目运行截图5.技术框架5.1后端采用SpringBoot框架5.2前端框架Vue6.选题推荐毕设案例8.系统测试8.1系统测试的目的8.2系统功能测试9.代码参考10.为什么选择我?11.获取源码1.前言......
  • 基于Java实现的家政服务管理平台设计与实现(SpringBoot+Vue+MySQL+Tomcat)
    文章目录1.前言2.详细视频演示3.论文参考4.项目运行截图5.技术框架5.1后端采用SpringBoot框架5.2前端框架Vue6.选题推荐毕设案例8.系统测试8.1系统测试的目的8.2系统功能测试9.代码参考10.为什么选择我?11.获取源码1.前言......