zoukankan      html  css  js  c++  java
  • Spring核心技术之定制bean属性 Mr

    Spring提供了几个标志接口,用来改变容器中bean的行为。包括InitializingBean和DisposableBean.实现这两个接口的bean在初始化和析构时,容器都会调用前者的afterPropertiesSet()方法,以及后者的destroy()方法。

    Spring在内部使用BeanPostProcessor实现来处理它能找到的任何标志接口并调用相应的方法。如果需要自定义特性或者生命周期行为,可以实现自己的BeanPostProcessor。关于这个请参照之前的容器扩展点。

    1)初始化回调:

    package springapp.test.beanCustomizing;
    
    import org.springframework.beans.factory.DisposableBean;
    import org.springframework.beans.factory.InitializingBean;
    
    /**         
     * @author zhangxuegang       
     * @version 1.0     
     * @created 2012-10-19 上午10:30:23    
     */
    
    public class ImplCustom implements InitializingBean,DisposableBean {
    
    	public ImplCustom(){
    		System.out.println("this is "+ImplCustom.class+"`s constractor method");
    	}
    	
    	@Override   //InitializingBean
    	public void afterPropertiesSet() throws Exception {
    		System.out.println("in "+ ImplCustom.class+" afterPropertiesSet() method");
    	}
    
    	@Override  //DisposableBean
    	public void destroy() throws Exception {
    		System.out.println("in "+ ImplCustom.class+" destroy() method");
    	
    }
    

    Xml配置

    <bean id="implCustom" class="springapp.test.beanCustomizing.ImplCustom"></bean>
    

    测试代码:

    package springapp.test.beanCustomizing;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.AbstractApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**     
     *      
     *     
     * @author zhangxuegang       
     * @version 1.0     
     * @created 2012-10-19 上午10:33:16    
     */
    
    public class TestCustom {
    	 public static void main(String[] args) throws Exception{
    	 ApplicationContext ctx = new ClassPathXmlApplicationContext(  
         "file:F:/springProject/springapp/war/WEB-INF/applicationTest.xml");
    	 ImplCustom impl = (ImplCustom) ctx.getBean("implCustom",ImplCustom.class);
    	 ((AbstractApplicationContext) ctx).registerShutdownHook();
    	 }
    }
    

    输出:

    this is class springapp.test.beanCustomizing.ImplCustom`s constractor method
    in class springapp.test.beanCustomizing.ImplCustom afterPropertiesSet() method
    in class springapp.test.beanCustomizing.ImplCustom destroy() method
    

    不过我们应该尽量避免使用这种方法,在上面的例子中我们可以看出,这种方法是与SPRING耦合在一起的,所以我们尽量使用普通的初始化方法即在XML配置文件中通过指定init-method属性来完成。

    修改后的代码:

    package springapp.test.beanCustomizing;
    
    /**         
     * @author zhangxuegang       
     * @version 1.0     
     * @created 2012-10-19 上午10:30:23    
     */
    
    public class ImplCustom1 {
    
    	public ImplCustom1(){
    		System.out.println("this is "+ImplCustom1.class+"`s constractor method");
    	}
    	
       public void init(){
    	   System.out.println("脱离spring,通过配置文件进行bean的定制");
       }
    }
    

    xml:

    <bean id="implCustom1" class="springapp.test.beanCustomizing.ImplCustom1" init-method="init"></bean>
    

    测试代码:

    package springapp.test.beanCustomizing;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.AbstractApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**     
     *      
     *     
     * @author zhangxuegang       
     * @version 1.0     
     * @created 2012-10-19 上午10:33:16    
     */
    
    public class TestCustom {
    	 public static void main(String[] args) throws Exception{
    	 ApplicationContext ctx = new ClassPathXmlApplicationContext(  
         "file:F:/springProject/springapp/war/WEB-INF/applicationTest.xml");
    	 ImplCustom1 impl1 = (ImplCustom1) ctx.getBean("implCustom1",ImplCustom1.class);
    	 ((AbstractApplicationContext) ctx).registerShutdownHook();
    	 }
    }
    

    输出:

    this is class springapp.test.beanCustomizing.ImplCustom`s constractor method
    in class springapp.test.beanCustomizing.ImplCustom afterPropertiesSet() method
    this is class springapp.test.beanCustomizing.ImplCustom1`s constractor method
    

    脱离spring,通过配置文件进行bean的定制

    in class springapp.test.beanCustomizing.ImplCustom destroy() method

    2)析构回调

    实现org.springframework.beans.factory.DisposableBean接口的bean允许在容器销毁该bean的时候获得一次回调。DisposableBean接口也只规定了一个方法void destroy() throws Exception;通常要避免使用DisposableBean标志接口,原因同上。我们可以在bean定义中指定一个普通的析构方法,即在XML配置文件中通过指定destroy-method属性来完成。

    因为上边的例子中已经使用了析构回调所以不在进行讲解

          

    3)缺省的初始化和析构方法

    如果我们都是通过设置bean的init-method或者destroy-method属性,由于初始化方法和析构方法的名字是可以任意指定的,所以这种回调方法的名字将各式各样,按照经验来说,最好在一个项目范围内标准化。

    那么如果将spring容器配置成在每个bean上查找事先指定好的初始化和析构回调方法名称。这样可以简化bean定义。例如,如果按照这样<beans default-init-method="init" >

    <bean id="blogServic" class="com.foo.DefaultBlogService">

    <property name="blogDao" ref="blogDao" />

    </bean>

    </beans>来配置的话,Spring Ioc容器会在bean被创建的时候调用该init方法。当然在DefaultBlogService类中要有public void init(){}方法。这样就不需要在每个bean中都配置init-mehtod属性了!同样,配置析构方法回调是在顶层<beans/>元素上使用default-destroy-method属性。

    最后补充一点,如果实际的回调方法与默认的命名约定不同时,那么可以通过在bean元素上使用init-method和destroy-method属性来指定方法名来覆盖缺省设置。

    在Spring2.5中有三种方式可以控制bean的生命周期行为: InitializingBean DisposableBean 回调接口;自定义init()destroy() 方法; @PostConstruct@PreDestroy annotations.

    当组合不同的生命周期机制时 - 例如,类层次中使用了不同的生命周期机制 - 开发者必须注意这些机制的应用顺序,下面是初始化方法中的顺序:

    • @PostConstruct元注释
    • InitializingBean的afterPropertiesSet()定义
    • 自定义init()方法配置

    析构方法的调用和初始化方法的顺序是一致的

    注意

    如果bean存在多种的生命周期机制配置并且每种机制都配置为不同的方法名, 那所有配置的方法将会按照上面的顺利执行。然而如果配置了相同的方法名 - 例如, init()初始化方法 - 采用多种机制配置后,只会执行一次。

    3.5.1.5. 在非web应用中优雅地关闭Spring IoC容器

    注意

    在基于web的ApplicationContext实现中已有相应的代码来处理关闭web应用时如何恰当地关闭Spring IoC容器。

    如果你正在一个非web应用的环境下使用Spring的IoC容器,例如在桌面富客户端环境下,你想让容器优雅的关闭,并调用singleton bean上的相应析构回调方法,你需要在JVM里注册一个“关闭钩子”(shutdown hook)。这一点非常容易做到,并且将会确保你的Spring IoC容器被恰当关闭,以及所有由单例持有的资源都会被释放(当然,为你的单例配置销毁回调,并正确实现销毁回调方法,依然是你的工作)。

    为了注册“关闭钩子”,你只需要简单地调用在AbstractApplicationContext实现中的registerShutdownHook()方法即可。也就是:

    其实上边的测试方法中我们用的就是此类方法:

    package springapp.test.beanCustomizing;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.AbstractApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**     
     *      
     *     
     * @author zhangxuegang       
     * @version 1.0     
     * @created 2012-10-19 上午10:33:16    
     */
    
    public class TestCustom {
         public static void main(String[] args) throws Exception{
         ApplicationContext ctx = new ClassPathXmlApplicationContext(  
         "file:F:/springProject/springapp/war/WEB-INF/applicationTest.xml");
         ImplCustom1 impl1 = (ImplCustom1) ctx.getBean("implCustom1",ImplCustom1.class);
         ((AbstractApplicationContext) ctx).registerShutdownHook();
         }
    }

     

    Mr-sniper
    北京市海淀区
    邮箱:rafx_z@hotmail.com
  • 相关阅读:
    Validation failed for one or more entities. See 'EntityValidationErrors' property for more details
    Visual Studio断点调试, 无法监视变量, 提示无法计算表达式
    ASP.NET MVC中MaxLength特性设置无效
    项目从.NET 4.5迁移到.NET 4.0遇到的问题
    发布网站时应该把debug设置false
    什么时候用var关键字
    扩展方法略好于帮助方法
    在基类构造器中调用虚方法需谨慎
    ASP.NET MVC中商品模块小样
    ASP.NET MVC中实现属性和属性值的组合,即笛卡尔乘积02, 在界面实现
  • 原文地址:https://www.cnblogs.com/rafx/p/customzingbean.html
Copyright © 2011-2022 走看看