`
beck5859509
  • 浏览: 108896 次
  • 性别: 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 BeanPostProcessor接口使用详解

    本篇文章主要介绍了Spring BeanPostProcessor接口使用详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    Java自定义注解与spring BeanPostProcessor详解

    NULL 博文链接:https://747017186.iteye.com/blog/2370422

    springframework.4.3.22.RELEASE

    Spring JavaMailSenderImpl does not show proper message when recipient list is empty [SPR-17540] #22072 Potential resource leak in DataSourceUtils.doGetConnection [SPR-17559] #22091 SpEL, error parsing...

    spring培训.pptx

    了解spring的加载机制 beanPostProcessor,beanFactoryPostProcessor 的使用 springmvc 的父子容器 aop切面说明 公司内部培训课件

    spring BeanPostProcessor 生命周期

    spring使用模板模式,在bean的创建过程中安插了许多锚点,用户寻找对应的锚点,通过重写方法介入到bean的创建过程当中。本节通过重写这些锚点,学习如何使用BeanPostProcessor、获取各类BeanAware并且理清bean的生命...

    spring3.1中文参考文档

    spring3.1中文参考文档,南磊翻译,现在有4章,目录如下: 第一部分 Spring framework概述.......................................................................................................................

    spring-framework-reference-4.1.2

    3. New Features and Enhancements in Spring Framework 4.0 ............................................ 17 3.1. Improved Getting Started Experience .........................................................

    spring-framework-reference4.1.4

    3. New Features and Enhancements in Spring Framework 4.0 ............................................ 17 3.1. Improved Getting Started Experience .........................................................

    Spring-Reference_zh_CN(Spring中文参考手册)

    2. Spring 2.0 的新特性 2.1. 简介 2.2. 控制反转(IoC)容器 2.2.1. 更简单的XML配置 2.2.2. 新的bean作用域 2.2.3. 可扩展的XML编写 2.3. 面向切面编程(AOP) 2.3.1. 更加简单的AOP XML配置 2.3.2. 对@AspectJ 切面的...

    Spring 2.0 开发参考手册

    3.7.1. 用BeanPostProcessor定制bean 3.7.2. 用BeanFactoryPostProcessor定制配置元数据 3.7.3. 使用FactoryBean定制实例化逻辑 3.8. ApplicationContext 3.8.1. 利用MessageSource实现国际化 3.8.2. 事件 ...

    详解使用Spring的BeanPostProcessor优雅的实现工厂模式

    主要介绍了详解使用Spring的BeanPostProcessor优雅的实现工厂模式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    SPRING API 2.0.CHM

    BeanPostProcessor BeanPropertyBindingResult BeanPropertySqlParameterSource BeanReference BeansDtdResolver BeansException BeanUtils BeanWiringInfo BeanWiringInfoResolver BeanWrapper ...

    Spring中文帮助文档

    3.7.1. 用BeanPostProcessor定制bean 3.7.2. 用BeanFactoryPostProcessor定制配置元数据 3.7.3. 使用FactoryBean定制实例化逻辑 3.8. The ApplicationContext 3.8.1. BeanFactory 还是 ApplicationContext? ...

    com-spring-ioc-demo:源码主要是学习Spring IOC的原理,以及对Bean的注册及控制,主要运用以下类对Spring进行扩展学习:BeanPostProcessor,BeanFactoryAware,BeanNameAware,ApplicationContextAware,FactoryBean,BeanDefinitionRegistryPostProcessor,BeanFactoryPostProcessor,BeanPostProcessor,ResourceLoaderA

    com-spring-ioc-demo:源码主要是学习Spring IOC的原理,以及对Bean的注册及控制,主要运用以下类对Spring进行扩展学习:BeanPostProcessor,BeanFactoryAware,BeanNameAware,ApplicationContextAware,FactoryBean...

    Spring API

    3.7.1. 用BeanPostProcessor定制bean 3.7.2. 用BeanFactoryPostProcessor定制配置元数据 3.7.3. 使用FactoryBean定制实例化逻辑 3.8. The ApplicationContext 3.8.1. BeanFactory 还是 ApplicationContext? ...

    spring chm文档

    3.7.1. 用BeanPostProcessor定制bean 3.7.2. 用BeanFactoryPostProcessor定制配置元数据 3.7.3. 使用FactoryBean定制实例化逻辑 3.8. ApplicationContext 3.8.1. 利用MessageSource实现国际化 3.8.2. 事件 ...

    feign-1.0.0.jar

    在spring的applicationContext.xml 里面配置 其中 feignScanBasePackage 表示要扫描接口包的地址,&lt;bean id="feignClientBeanPostProcessor" class="com.yax.feign.beanPostProcessor.FeignClientBeanPostProcessor...

    通俗易懂的Spring注解驱动开发教程(含配套资料)

    后置处理器(BeanPostProcessor.BeanFactoryPostProcessor等) 2).监听器(ApplicationListener) 3).Spring容器启动过程; 3).web原理 1).Servlet3.0标准新增特性 2).异步请求相关 本视频使用了maven...

    Spring 3 Reference中文

    第一部分 Spring framework 概述..5 第1 章 Spring Framework 介绍..6 1.1 依赖注入和控制反转.6 1.2 模块6 1.2.1 核心容器.7 1.2.2 数据访问/ 整合..7 1.2.3 Web ..8 1.2.4 AOP...

Global site tag (gtag.js) - Google Analytics