您的位置:首页 > 编程语言 > Java开发

基于Spring容器Bean的动态注入

2017-09-02 23:54 381 查看
首先对BeanPostProcessor,BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor做个整理。

BeanPostProcessor: Spring容器Bean的后置回调接口,即每个Bean在实例化之前都会调用BeanPostProcessor里的postProcessBeforeInitialization和postProcessAfterInitialization方法。

测试实例: 
package com.harry.spring4.demo3;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class TestBeanPostPocesser implements BeanPostProcessor {

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("--postProcessBeforeInitialization---" + bean.getClass());
return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("--postProcessAfterInitialization--" + bean.getClass());
return bean;
}

}


运行结果:



BeanFactoryPostProcessor: 容器的初始化回调,只会执行一次,在BeanFatory初始化后,Bean的初始化之前(通过Bean的Init方法测试)执行

测试用例:

package com.harry.spring4.demo3;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

/**
* 容器的初始化回调
* 只会执行一次,在BeanFactory初始化完成之后,只会出发一次,可以在postProcessBeanFactory方法中做相关处理
* 在Bean初始化之前就会执行(Bean的init方法之前)
* @author Harry Wan
*
*/
@Component
public class TestFactoryPostProcessor implements BeanFactoryPostProcessor{

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("容器中一共有:" + beanFactory.getBeanDefinitionCount() + " 个Bean!");
}

}


运行结果:



BeanDefinitionRegistryPostProcessor: 可以获取到BeanDefinitionRegistry对象,通过BeanDefinitionRegistry对象来实现Bean的动态注入

测试用例:
package com.harry.spring4.demo3;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.stereotype.Component;

/**
* BeanDefinitionRegistryPostProcessor可以获取到BeanDefinitionRegistry对象
* BeanDefinitionRegistry可以动态的注入Bean到Spring容器中
* @author Harry Wan
*
*/
@Component
public class TestBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// TODO Auto-generated method stub

}

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
BeanDefinitionBuilder builder1 = BeanDefinitionBuilder.genericBeanDefinition(MyBean.class);
registry.registerBeanDefinition("xyz", builder1.getBeanDefinition());
for (int i = 0; i < 5; i++) {//这里动态注入5个Bean
//获取基于MyBean2 的定义
BeanDefinitionBuilder builder2 = BeanDefinitionBuilder.genericBeanDefinition(MyBean2.class);
builder2.addPropertyValue("name", "zhangsan" + i);
//属性依赖MyBean,确保MyBean一再容器中
//builder2.addPropertyReference("abc", "createMyBean");//@Bean(name="createMyBean")
builder2.addPropertyReference("abc", "xyz");//动态手动注入MyBean实例
registry.registerBeanDefinition(i + "", builder2.getBeanDefinition());
}
}

}


package com.harry.spring4.demo3;

import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MyDemo3 {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext("com.harry.spring4.demo3");
applicationContext.registerBeanDefinition("instanceMyBeanType2", BeanDefinitionBuilder.genericBeanDefinition(MyBean.class).getBeanDefinition());
System.out.println(applicationContext.getBeansOfType(MyBean2.class));
System.out.println(applicationContext.getBeansOfType(MyBean.class));

applicationContext.close();
}
}

package com.harry.spring4.demo3;

public class MyBean2 {
private MyBean abc;

private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public MyBean getAbc() {
return abc;
}

public void setAbc(MyBean abc) {
this.abc = abc;
}

@Override
public String toString() {
return "MyBean2 [abc=" + abc + ", name=" + name + "]";
}

}

总结:这里通过BeanDefinitionRegistry对象向Spring容器动态注入Bean,利用BeanDefinitionBuilder获取目标Bean的定义BeanDefinition,在注入Bean的同时,可以设置属性的值,以及属性的引用,在设置属性的引用时,要注意被引用的Bean的实例已经配置在容器中,所引用的Bean的实例也可以通过动态注入到Spring容器中或者通过注解注入。

applicationContext.registerBeanDefinition("instanceMyBeanType2", BeanDefinitionBuilder.genericBeanDefinition(MyBean.class).getBeanDefinition());

你也可以通过ApplicationContext提供的手动注入方式注入,其参数以及原理和实现BeanDefinitionRegistryPostProcessor借口一致。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring 动态注入