`
beck5859509
  • 浏览: 111268 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

如何玩转Spring的BeanPostProcessor.

    博客分类:
  • java
 
阅读更多
    在Spring初始化bean的步骤中,有一步执行前缀/后置初始化的处理(BeanPostProcessor)的逻辑。这为我们提供了扩展Bean的功能,IOC的强大功能就在于此。

    在讲解之前,这里要说一下InitializingBean和BeanPostProcessor的区别,必免混淆。两个接口都可以执行bean初始化前置处理的功能。区别在于InitializingBean是目标Bean主动实现的接口(常用业务逻辑可以写在里面),而BeanPostProcessor是由BeanFatotry在Bean初始化时把Bean作为参数传入BeanPostProcessor执行的(具体BeanPostProcessor是被存储在AbstractBeanFactory中的一个List中)。暂且说成被动执行。

    BeanPostProcessor的实现类主要是Spring自带的一些辅助类,比如注解扫描类(CommonAnnotationBeanPostProcessor,xml中配置为<context:component-scan> ),配置以后会自动扫描标记了@Controller,@Service等注解的类,提供给其它类进行注入。

    下面介绍另一个配合hibernate使用BeanPostProcessor的另一个场景。我们有这样一种场景,如何让容器在启动的时候加载各模块之间配置的mapping文件呢。

     首先看一下常规的做法,在sessionFactory中显示的配置。
	<bean id="routeSessionFactory" name="routeSessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource" ref="routeDataSourceLocal" />
		<property name="mappingResources">
			<list>
				<value>com/sf/module/routeshare/META-INF/config/mapping.xml</value>
.....//添加其它mapping.xml文件
			</list>
		</property>

    此种做法不好的地方在于多个模块同时开发时,需要修改同一个文件,不利于管理。

    其实BeanPostProcessor提供了一种便捷的方式,在容器启动时,先收集好mapping.xml文件的位置,在实例化LocalSessionFactoryBean时把mapping数组注入到mappingResources属性中。
    具体步骤如下:
    1.web.xml中配置容器启动后的监听器。
  <listener>
    <listener-class>com.xxx.framework.server.core.deploy.FrameworkListener</listener-class>
  </listener>


    2.加载所有mapping文件的路径。
    //始始化容器时读取mapping文件路径。
    private Application initApplication()
    {
       //加载指定路径下各模块的mapping.xml文件。
       List mappingConfigs = initConfigs("/META-INF/config/mapping.xml", 
moduleNames);
...}

    //使用spring工具类进行解析
    private List initConfigs(String configName, List configs)
    {
        try
        {   
            Resource resources[] = new PathMatchingResourcePatternResolver().getResources((new StringBuilder("classpath*:com/xxx/**")).append(configName).toString());
            for(int i = 0; i < resources.length; i++)
            {
                Resource resource = resources[i];
                try
                {
                    String file = resource.getURL().getPath();
                    String config = file.substring(file.lastIndexOf("com/sf/"));
                    if(!configs.contains(config))
                    {
                        configs.add(config);
                    }
                    .....
					
	}


       3.编写BeanPostProcessor。
public class MappingAutowiring
    implements BeanPostProcessor
{

    public MappingAutowiring()
    {
    }

    public String[] getMappingResources()
    {
        return mappingResources;
    }
    
    //此方法通过MappingFactoryBean进行注入,里面会获取到之前Application的mapping的路径
    public void setMappingResources(String mappingResources[])
    {
        this.mappingResources = mappingResources;
    }

    public Object postProcessBeforeInitialization(Object bean, String beanName)
        throws BeansException
    {
        if(bean instanceof LocalSessionFactoryBean)
        {
            log.debug((new StringBuilder("============ MappingAutowiring: ")).append(mappingResources).toString());
            ((LocalSessionFactoryBean)bean).setMappingResources(mappingResources);
        }
        return bean;
    }

<!--配置MappingAutowiring -->
<bean id="mappingAutowiring" class="com.xxx.framework.server.core.deploy.MappingAutowiring">
		<property name="mappingResources" ref="mappingResources" />
	</bean>
	<bean id="mappingResources" class="com.xxx.framework.server.core.deploy.MappingFactoryBean" />


public class MappingFactoryBean
    implements FactoryBean
{
    public MappingFactoryBean(){}

    public Object getObject()
        throws Exception
    {
        List configs = ApplicationContext.getContext().getApplication().getMappingConfigs();
       
        return ((Object) (configs.toArray(new String[configs.size()])));
    }
	
    ....
}

    从上述代码看出,通过BeanPostProcessor的postProcessBeforeInitialization方法,可以给LocalSessionFactoryBean注入mapping文件的路径
0
0
分享到:
评论

相关推荐

    一篇文章带你玩转Spring bean的终极利器

    Spring Bean的终极利器——BeanPostProcessor(BPP)接口,提供了一种强大的方式来扩展Spring容器的行为,允许我们在Bean实例化、属性设置、初始化方法调用等关键阶段进行干预。本文将深入讲解BPP的工作原理和应用...

    Spring中眼花缭乱的BeanDefinition.docx

    Spring中的BeanDefinition是核心概念,...因此,想要真正玩转Spring,阅读源码并理解BeanDefinition的实现细节是非常必要的。通过这个过程,可以更好地理解Spring如何实现IoC和AOP,以及如何优雅地管理Bean的生命周期。

    基于STM32蓝牙控制小车系统设计(硬件+源代码+论文)

    基于STM32蓝牙控制小车系统设计(硬件+源代码+论文)

    某汽车联合车间工艺布置图.zip

    某汽车联合车间工艺布置图.zip

    统计学中的因果推断.pdf

    统计学中的因果推断

    轻量级的PHP地址发布页源码.zip

    1:后台登录地址为/admin/login.php,提供便捷的配置入口。 2:默认用户名是admin,密码为password123,首次登录后可。 3:使用方法:上传到虚拟机或服务器并解压,访问首页查看效果, 4:进入后台可编辑3个固定修改链接、添加或删除额外链接、设置底部文字及选择模板。 5:底部文字通过转义处理,不支持HTML,确保输出安全。 6:无论是个人项目还是分享导航,LinkEase都提供简单的解决方案。

    blast_furnace_front_on.png

    blast_furnace_front_on

    wither_rose.png

    j

    h5py-3.13.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

    该资源为h5py-3.13.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl,欢迎下载使用哦!

    【数字图像处理】形态学处理与纹理分析技术:边界提取、孔洞填充及组件标记的应用研究

    内容概要:本文档是关于数字图像处理课程作业的报告,主要分为两个部分:形态学处理和纹理分析。形态学处理部分涵盖边界提取、孔洞填充和组件标记三个任务,详细描述了每个任务的具体步骤和方法,如通过形态学方法找到白色图案的内部区域并进行边界提取,利用连通分量标记技术进行孔洞填充,以及采用4邻接和8邻接方式对对象进行组件标记。纹理分析部分则介绍了使用Law's方法获取特征向量的过程,包括卷积和能量计算,还展示了如何用K-means算法对像素进行分类,并提出了一些改进措施,如调整窗口大小、优化K值选择等。 适合人群:具有图像处理基础知识的学生或研究人员,特别是正在学习数字图像处理课程的人士。 使用场景及目标:①帮助学生理解形态学处理的基本概念和技术,如边界提取、孔洞填充和组件标记;②指导学生掌握纹理分析的方法,如Law's方法和K-means聚类算法的应用;③通过实例操作提高学生的实践能力和问题解决能力。 阅读建议:此文档为课程作业报告,内容较为具体和技术化,建议读者先了解基本的形态学处理和纹理分析理论,再结合文档中的具体步骤进行实践操作,以便更好地理解和掌握相关知识。

    MP0 Set up xv6.pdf操作系统基于Docker和QEMU的xv6环境搭建与简单进程通信实验:教学操作系统实践

    内容概要:本文介绍了如何设置xv6操作系统的学习环境。xv6是MIT创建的一个用于教学的类Unix内核示例。文章首先解释了为什么选择Docker作为虚拟化工具,强调了其轻量级的特点,并指导读者安装Docker。接着详细描述了从克隆GitHub仓库到加载Docker镜像的具体步骤,以及如何使用QEMU模拟器在非RISC-V架构上启动xv6。最后提供了一个简单的练习,要求编写一个名为detective的程序,利用UNIX系统调用来查找特定名称的文件,并通过管道在父子进程间通信。 适合人群:具备一定C语言编程能力和系统编程经验的学生或开发者,尤其是对操作系统原理感兴趣的人士。 使用场景及目标:①学习Docker的安装与配置,理解容器化技术的优势;②掌握xv6内核的基本操作,包括编译和运行;③通过完成detective程序,深入理解进程管理、文件系统遍历和进程间通信等操作系统核心概念。 阅读建议:建议读者按照文档逐步实践,确保每一步都能成功执行。由于部分命令和工具基于Linux平台,推荐在Linux环境下进行操作。此外,在动手之前先阅读xv6参考书籍的第一章,有助于更好地理解和完成练习。

    糖化、水罐及CIP工艺流程.rar

    糖化、水罐及CIP工艺流程.rar

    activator_rail_on.png

    activator_rail_on

    液压剪式升降平台(step SolidWorks)设计.rar

    液压剪式升降平台(step SolidWorks)设计.rar

    【操作系统领域】HarmonyOS的Linux内核子集(LOS)技术解析:智能设备核心支撑与未来发展趋势

    内容概要:本文详细介绍了HarmonyOS及其Linux内核子集(LOS)。HarmonyOS是华为自主研发的面向全场景的分布式操作系统,旨在打破国外操作系统垄断,推动国产操作系统发展。LOS作为HarmonyOS的重要组成部分,位于内核层,负责管理硬件资源、内存、文件系统和网络等。LOS具有虚拟内存管理、进程隔离、强大的网络支持、高效的文件系统、多线程编程支持和任务调度机制等技术特点。LOS在智能手机、智能家居设备和智能穿戴设备等领域发挥了重要作用,确保了系统的性能、稳定性和低功耗。与Linux原生内核和鸿蒙微内核相比,LOS在功能特性、性能表现和适用场景上有明显优势,并且与鸿蒙微内核协同工作,共同推动HarmonyOS的发展。未来,LOS将在安全性、性能优化和新功能支持等方面取得更大突破,推动HarmonyOS生态的繁荣发展。 适合人群:对操作系统底层技术感兴趣的开发者、科技爱好者以及从事智能设备相关领域的工程师。 使用场景及目标:①深入了解HarmonyOS及其内核子集(LOS)的技术特点和应用场景;②为开发基于HarmonyOS的智能设备提供理论支持和技术参考;③探索LOS在不同智能设备中的优化和应用,推动智能设备的创新和发展。 其他说明:本文不仅介绍了LOS的技术细节,还探讨了其与鸿蒙微内核的区别和协同工作方式,以及对未来发展的展望。这有助于读者全面理解HarmonyOS的内核架构和技术优势,为未来的开发和研究提供指导。

    第三章习题作业.docx

    第三章习题作业.docx

    openssl-3.5.0-multiple-Kylin-Server-V10-GFB-arm64.tar.gz

    为了解决信创环境下不能连网,因此在Kylin Server V10 下编译了openssl最新版本,而且做成了离线安装的脚本,安装步骤如下所示: 1. 解压软件包 [root@daolian ~]# tar -zxvf openssl-3.5.0-202504152120-multiple-Kylin-Server-V10-GFB-arm64.tar.gz 2. 查看目录中内容 [root@daolian nginx]# ls openssl.tar.gz setup.sh 3.安装 [root@daolian openssl]# ./setup.sh OPENSSL 3.5.0 INSTALL Sucesses 4.查看版本号 root@daolian:~# openssl version -a OpenSSL 3.5.0 8 Apr 2025 (Library: OpenSSL 3.5.0 8 Apr 2025) built on: Tue Apr 15 12:43:51 2025 UTC platform: linux-aarch64 options: bn(64,64)

    模具-Φ146.6药瓶注塑模设计.zip

    模具-Φ146.6药瓶注塑模设计.zip

    h5py-3.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

    该资源为h5py-3.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl,欢迎下载使用哦!

    基于Python的模仿元气骑士的游戏.zip

    基于Python的模仿元气骑士的游戏

Global site tag (gtag.js) - Google Analytics