编程方式实现SpringBean LazyInit
来源:互联网 发布:linux中查找文件命令 编辑:程序博客网 时间:2024/04/28 21:10
背景:
工程单元测试希望和生产环境应用共用一份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.
接口代码如下:
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对象,见:
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)
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)
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 void init() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
//ignore
System.out.println(e);
}
System.out.println("TestBean Init");
}
}
Spring配置爱之谷文件:
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>
测试代码:
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 }
大功告成.收工. :)
- 编程方式实现SpringBean LazyInit
- SpringBean
- 一步步实现:springbean的生命周期测试代码
- Springboot 中同时使用mybatis注解和springbean-xml配置方式
- 注解方式实现AOP编程
- XML方式实现AOP编程
- 安全编程的实现方式
- UDP通讯方式及编程实现步骤
- UDP通讯方式及编程实现步骤
- UDP通讯方式及编程实现步骤
- 利用Annotation方式实现AOP编程
- UDP通讯方式及编程实现步骤
- C#通过编程方式实现Ping
- (转)几种方式实现串口编程
- 编程实现短信发送三种方式
- Android 串口编程原理和实现方式
- 并行编程的实现方式与语言
- 注解方式实现AOP切面编程
- 职场成功的秘诀-自信心
- SQL SERVER中的union,cube,rollup和cumpute运算符
- glscene
- 互联网数据分析和挖掘公开课程
- 开通博客
- 编程方式实现SpringBean LazyInit
- QTP数据库一块知识
- 杭州Cognos8项目开发培训6月端午假期公开课开始招生
- 关于“迷茫”,摘自秋叶的博客
- Ecplses+axis+BPEL2.0实现:BPEL调用加减法的Web服务,进行加减运算
- update
- it人才需求巨大
- 关于Java缺乏多继承机制的探讨
- 文件流实现上传下载