`
beck5859509
  • 浏览: 110338 次
  • 性别: 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类图.zip

    `BeanPostProcessor.png`可能是这个类图的可视化表示,直观地展示了BeanPostProcessor在Spring容器中的工作原理。图片可能会包含各个处理阶段的流程图,帮助开发者更好地理解和应用这个接口。 `...

    官方原版源码 spring-5.2.8.RELEASE.zip

    此外,Spring的事务管理(`org.springframework.transaction`包)是其另一大亮点,提供了声明式事务管理,使得开发者无需显式调用begin、commit或rollback,即可实现事务控制。 Spring框架5.2.8.RELEASE的源码不仅...

    Spring BeanPostProcessor接口使用详解

    Spring BeanPostProcessor接口使用详解 Spring BeanPostProcessor接口是Spring框架中的一种后处理器接口,允许开发者在Bean初始化前后进行自定义处理。该接口提供了两个供开发者自定义的方法:...

    Java自定义注解与spring BeanPostProcessor详解

    Java自定义注解和Spring的BeanPostProcessor是Java企业级开发中的两个重要概念,它们在构建灵活、可扩展的应用程序中发挥着关键作用。本文将深入探讨这两个话题,并结合源码分析,帮助开发者更好地理解和应用。 ...

    《精通Spring2.X企业应用开发详解》

    ### 《精通Spring2.X企业应用开发详解》第五章知识点详解 #### 5.1 Spring容器技术内幕 ##### 5.1.1 内部工作机制 Spring容器作为一款设计精妙且功能强大的框架核心,其内部机制对于理解和掌握Spring的工作原理至...

    spring-framework-4.3.17 源码包

    在源码中,`org.springframework.beans.factory` 和 `org.springframework.context` 包下包含了IoC容器的主要实现。 2. AOP:AOP是Spring提供的一种面向切面编程的能力,允许开发者定义“切面”,并在适当的时间...

    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容器 .ppt

    它们都是实现`org.springframework.beans.factory.BeanFactory`接口的实例。 2. **容器和Bean** - **BeanFactory**:这是Spring中最基本的容器,它负责加载配置文件,解析Bean定义,然后根据这些定义实例化Bean。...

    Spring Framework 3.0.0.4

    总的来说,Spring Framework 3.0.0.4中的IoC容器是通过`org.springframework.beans`包提供的服务来实现的,这些服务涵盖了bean的定义、创建、配置、依赖注入等多个方面,为Java开发者提供了强大的工具来管理应用的...

    spring-framework-5.2.0.RELEASE-master.zip

    在源码中,`org.springframework.beans.factory`和`org.springframework.context`这两个包下的类和接口,如`BeanFactory`和`ApplicationContext`,是实现IOC的关键。 **Spring AOP(Aspect Oriented Programming)*...

    spring ioc.rar

    10. **容器扩展点**: Spring提供了一些扩展点,如BeanPostProcessor、InstantiationAwareBeanPostProcessor等,允许在bean初始化前后进行自定义处理。 以上是关于Spring IOC的一些基本概念和核心知识点,通过这些...

    spring-beans-3.0.2.RELEASE.jar.zip

    SpringBeans-3.0.2.RELEASE.jar还包含了一些关键接口,如BeanPostProcessor允许自定义Bean实例化后的处理逻辑,InitializingBean和DisposableBean分别用于标识初始化和销毁方法。同时,该版本的Spring支持AOP(面向...

    spring-framework-2.5.4源码.rar

    在源码中,`org.springframework.beans`和`org.springframework.context`包提供了实现,如`BeanFactory`和`ApplicationContext`接口。通过XML配置或注解,开发者可以声明对象及其依赖,让Spring来创建和管理这些对象...

    spring培训.pptx

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

    Spring.pdf

    4. BeanPostProcessor的前置处理:在Bean的初始化方法调用之前,Spring允许BeanPostProcessor的postProcessBeforeInitialization方法对Bean实例进行额外的处理。 5. 初始化方法:若Bean在配置中指定了init-method,...

    spring BeanPostProcessor 生命周期

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

    spring源代码

    在`org.springframework.beans`包下,`BeanDefinition`类存储了bean的元数据,`BeanPostProcessor`接口允许自定义bean初始化前后的行为。`@Autowired`注解是自动装配依赖的常用方式,源码中在`org.springframework....

    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 .........................................................

Global site tag (gtag.js) - Google Analytics