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
  • 相关阅读:
    ab性能测试工具
    Web_add_cookie的作用
    loadrunner录制时,设置能不记录所有的事件
    oracle插入数据问题
    LR检查点
    LoadRunner 一参多用
    loadrunner 脚本中文乱码
    LoadRunner参数化取值与连接数据库
    LoadRunner中的随机数
    loadrunner 的Administration Page里面设置
  • 原文地址:https://www.cnblogs.com/rafx/p/customzingbean.html
Copyright © 2011-2022 走看看