基于Spring容器Bean的动态注入
2017-09-02 23:54
381 查看
首先对BeanPostProcessor,BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor做个整理。
运行结果:
运行结果:
总结:这里通过BeanDefinitionRegistry对象向Spring容器动态注入Bean,利用BeanDefinitionBuilder获取目标Bean的定义BeanDefinition,在注入Bean的同时,可以设置属性的值,以及属性的引用,在设置属性的引用时,要注意被引用的Bean的实例已经配置在容器中,所引用的Bean的实例也可以通过动态注入到Spring容器中或者通过注解注入。
你也可以通过ApplicationContext提供的手动注入方式注入,其参数以及原理和实现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中的Bean实例快速指南
- Spring动态的注入Bean对象的实现方式,
- spring容器通过动态代理获取bean
- 使用telnet连接到基于spring的应用上执行容器中的bean的任意方法
- 五、Spring容器中Bean的属性值的注入
- Spring之手动启动容器并打印已注入的Bean
- 配置springmvc在其他类中(spring容器外)获取注入bean
- 从0开始写一个基于注解的轻量级分布式RPC框架(4)自定义Spring的IOC,自定义属性注入bean的过程
- JSP页面调用Spring容器注入的Bean
- 在servlet中注入spring容器中的bean
- 理解spring的BeanDefinition和配置文件(原文标题:动态注册bean到spring容器)
- spring中基于BeanPostProcessor动态替换指定的bean
- 101. Spring Boot轻松理解动态注入,删除bean【从零开始学Spring Boot】
- 【JavaWeb-23】spring、IoC控制反转和DI依赖注入入门、基于XML的Bean装配、基于注解的Bean装配
- JAVA WEB 过滤器(Filter)中向容器 Spring 注入 bean
- Spring IOC容器中注入bean
- spring中基于BeanFactoryAware动态替换指定的bean
- 在Spring中,动态注入Bean
- 如何在JSP页面中调用Spring容器注入的Bean?
- jsp自定标签(并且注入spring容器中的bean)