<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    stone2083

    編程方式實現SpringBean LazyInit

    Tags:
    Spring  LazyInit DocumentDefaultsDefinition ReaderEventListener AbstractXmlApplicationContext

    背景:
    工程單元測試希望和生產環境應用共用一份Spring配置文件.
    生產環境應用為了客戶體驗使用非LazyInit模式,但是單元測試下為了當前測試提高響應時間,希望設置LazyInit.

    分析源代碼,得知,Spring在解析XML時,會將Bean默認配置,放入到DocumentDefaultsDefinition對象中,其中包含lazyInit.
    DocumentDefaultsDefinition注釋如下:
    Simple JavaBean that holds the defaults specified at the <beans> level in a standard Spring XML bean definition document: default-lazy-init, default-autowire, etc

    Spring是否提供了入口點,進行DocumentDefaultsDefinition的修改呢?
    詳見:ReaderEventListener,注釋如下:
    Interface that receives callbacks for component, alias and import registrations during a bean definition reading process
    在BeanDefinition分析過程中,對component,alias,import registrations,defaults registrations提供一組callbacks.

    接口代碼如下:
     1 public interface ReaderEventListener extends EventListener {
     2 
     3     /**
     4      * Notification that the given defaults has been registered.
     5      * @param defaultsDefinition a descriptor for the defaults
     6      * @see org.springframework.beans.factory.xml.DocumentDefaultsDefinition
     7      */
     8     void defaultsRegistered(DefaultsDefinition defaultsDefinition);
     9 
    10     /**
    11      * Notification that the given component has been registered.
    12      * @param componentDefinition a descriptor for the new component
    13      * @see BeanComponentDefinition
    14      */
    15     void componentRegistered(ComponentDefinition componentDefinition);
    16 
    17     /**
    18      * Notification that the given alias has been registered.
    19      * @param aliasDefinition a descriptor for the new alias
    20      */
    21     void aliasRegistered(AliasDefinition aliasDefinition);
    22 
    23     /**
    24      * Notification that the given import has been processed.
    25      * @param importDefinition a descriptor for the import
    26      */
    27     void importProcessed(ImportDefinition importDefinition);
    28     
    29 }

    接下去分析,ReaderEventListener是在哪個入口點,提供了回調.答案是XmlBeanDefinitionReader.
    在AbstractXmlApplicationContext,創建了XmlBeanDefinitionReader對象,見:
     1 public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext {
     2     
     3     /**
     4      * Loads the bean definitions via an XmlBeanDefinitionReader.
     5      * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
     6      * @see #initBeanDefinitionReader
     7      * @see #loadBeanDefinitions
     8      */
     9     protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException {
    10         // Create a new XmlBeanDefinitionReader for the given BeanFactory.
    11         XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
    12 
    13         // Configure the bean definition reader with this context's
    14         // resource loading environment.
    15         beanDefinitionReader.setResourceLoader(this);
    16         beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
    17 
    18         // Allow a subclass to provide custom initialization of the reader,
    19         // then proceed with actually loading the bean definitions.
    20         initBeanDefinitionReader(beanDefinitionReader);
    21         loadBeanDefinitions(beanDefinitionReader);
    22     }
    23 
    24 }

    我們只需要去復寫這個方法,在創建XmlBeanDefinitionReader的時候,去注入EventListener即可.

    擴展代碼如下:
    LazyInitListener.java (不管配置文件如何配置,設置默認的LazyInit為true)
    public class LazyInitListener implements ReaderEventListener {

        
    private static final String LAZY_INIT = "true";

        @Override
        
    public void defaultsRegistered(DefaultsDefinition defaultsDefinition) {
            
    //set lazy init true
            if (defaultsDefinition instanceof DocumentDefaultsDefinition) {
                DocumentDefaultsDefinition defaults 
    = (DocumentDefaultsDefinition) defaultsDefinition;
                defaults.setLazyInit(LAZY_INIT);
            }
        }

        @Override
        
    public void aliasRegistered(AliasDefinition aliasDefinition) {
            
    //no-op
        }

        @Override
        
    public void componentRegistered(ComponentDefinition componentDefinition) {
            
    //no-op
        }

        @Override
        
    public void importProcessed(ImportDefinition importDefinition) {
            
    //no-op
        }

    }

    LazyInitClasspathXmlApplicationContext.java (復寫AbstractXmlApplicationContext,創建XmlBeanDefinitionReader的時候注入LazyInitListener)
     1 public class LazyInitClasspathXmlApplicationContext extends ClassPathXmlApplicationContext {
     2 
     3     public LazyInitClasspathXmlApplicationContext(String location) {
     4         super(location);
     5     }
     6 
     7     @Override
     8     protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException {
     9         // Create a new XmlBeanDefinitionReader for the given BeanFactory.
    10         XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
    11 
    12         // Configure the bean definition reader with this context's
    13         // resource loading environment.
    14         beanDefinitionReader.setResourceLoader(this);
    15         beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
    16 
    17         // 添加的代碼,設置LazyInitListener
    18         beanDefinitionReader.setEventListener(new LazyInitListener());
    19 
    20         // Allow a subclass to provide custom initialization of the reader,
    21         // then proceed with actually loading the bean definitions.
    22         initBeanDefinitionReader(beanDefinitionReader);
    23         loadBeanDefinitions(beanDefinitionReader);
    24     }
    25 
    26 }

    演示代碼如下:
    TestBean:一個Spring Bean對象
    public class TestBean {

        
    public void init() {
            
    try {
                Thread.sleep(
    5000);
            } 
    catch (InterruptedException e) {
                
    //ignore
                System.out.println(e);
            }
            System.out.println(
    "TestBean Init");
        }
    }

    Spring配置文件:
    1 <?xml version="1.0" encoding="UTF-8"?>
    2 <beans xmlns="http://www.springframework.org/schema/beans"
    3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    5 
    6     <bean id="testBean" class="com.alibaba.javalab.spring.lazy.TestBean" init-method="init" />
    7 </beans>

    測試代碼:
     1 public class Run {
     2 
     3     private static final String CONFIG = "classpath:spring/bean.xml";
     4 
     5     public static void main(String[] args) {
     6         testInit();
     7         System.out.println("===============================");
     8         testLazyInit();
     9     }
    10 
    11     public static void testInit() {
    12         new ClassPathXmlApplicationContext(CONFIG);
    13     }
    14 
    15     public static void testLazyInit() {
    16         new LazyInitClasspathXmlApplicationContext(CONFIG);
    17     }
    18 }


    大功告成.收工. :)

    posted on 2010-06-03 12:46 stone2083 閱讀(3163) 評論(2)  編輯  收藏 所屬分類: java

    Feedback

    # re: 編程方式實現SpringBean LazyInit 2010-06-19 01:11 stone2083

    今天又細看了代碼,發現覆寫
    AbstractXmlApplicationContext.initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) 方法更為合理.  回復  更多評論   

    # re: 編程方式實現SpringBean LazyInit[未登錄] 2010-07-07 15:26 zhao

    你好強啊!  回復  更多評論   

    主站蜘蛛池模板: 亚洲午夜成人精品无码色欲| 亚洲精品国产美女久久久| 中文字幕亚洲综合精品一区| 久久99精品免费一区二区| 亚洲精品成人区在线观看| 日日躁狠狠躁狠狠爱免费视频 | 最近免费中文字幕中文高清| 一本色道久久综合亚洲精品高清 | 亚洲国产精品无码成人片久久| 一个人看的www免费在线视频| 国产成人精品日本亚洲专区| 亚洲黄片手机免费观看| 亚洲av永久无码制服河南实里| 免费一本色道久久一区| 亚洲jizzjizz在线播放久| 性xxxx视频播放免费| 老司机亚洲精品影院在线观看| 亚洲电影日韩精品| 免费a级毛片无码a∨免费软件| 精品亚洲aⅴ在线观看| 猫咪免费人成网站在线观看入口| 免费a级毛片大学生免费观看| 好吊色永久免费视频大全| 亚洲国产高清在线| 歪歪漫画在线观看官网免费阅读| 亚洲精品第一国产综合亚AV| 亚洲欧洲中文日韩av乱码| 久久久久国产精品免费看| 亚洲欧洲另类春色校园网站| 丁香亚洲综合五月天婷婷| 国产麻豆成人传媒免费观看| 亚洲伊人久久大香线蕉在观| 国产精品成人四虎免费视频| 亚洲精品黄色视频在线观看免费资源 | 日本免费网站视频www区| 日本亚洲免费无线码| 亚洲成?v人片天堂网无码| 免费毛片a线观看| 亚洲一卡2卡三卡4卡无卡下载| 亚洲AⅤ优女AV综合久久久| 日本卡1卡2卡三卡免费|