Spring高级-容器实现-BeanFactory后处理器排序(一)
一、开胃菜:入门级面试题:如果一个接口有多个实现类,想取到其中某一个Bean怎么进行一个依赖注入
1、代码
package com.mangoubiubiu.show; import lombok.extern.slf4j.Slf4j; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.annotation.AnnotationConfigUtils; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.logging.Logger; public class TestBeanFactory { public static void main(String[] args) { DefaultListableBeanFactory beanFactory=new DefaultListableBeanFactory(); //bean 的定义 (class ,scope , 初始化 ,销毁方法) AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition(); beanFactory.registerBeanDefinition("config",beanDefinition); //给 BeanFactory 添加一些常用的后处理器 AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory); //BeanFactory 后处理器主要功能,补充了一些bean的定义 beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().stream().forEach(beanFactoryPostProcessor -> { beanFactoryPostProcessor.postProcessBeanFactory(beanFactory); }); //Bean后处理器,针对 bean 的生命周期的各个阶段提供扩展,例如@Autowired @Resource // beanFactory.getBeansOfType(BeanPostProcessor.class).values().forEach(beanFactory::addBeanPostProcessor); beanFactory.getBeansOfType(BeanPostProcessor.class).values().forEach(beanPostProcessor -> { beanFactory.addBeanPostProcessor(beanPostProcessor);//建立bean工厂与后处理器之间的联系 }); for(String name : beanFactory.getBeanDefinitionNames()){ System.out.println(name); } beanFactory.preInstantiateSingletons();//准备好所有的单列对象 System.out.println("----------------->"); Bean1 bean = beanFactory.getBean(Bean1.class); System.out.println("成功取到Bean2的对象:"+bean.getBean2()); System.out.println("----------------->"); System.out.println("成功取到Bean2的对象:"+bean.getInner()); } @Configuration static class Config{ @Bean public Bean1 bean1(){ return new Bean1(); } @Bean public Bean2 bean2(){ return new Bean2(); } @Bean public Bean3 bean3(){ return new Bean3(); } @Bean public Bean4 bean4(){ return new Bean4(); } } interface Inner{ } static class Bean3 implements Inner{} static class Bean4 implements Inner{} @Slf4j static class Bean1 { public Bean1(){ log.info("构造 Bean1"); } @Autowired private Bean2 bean2; public Bean2 getBean2(){ return bean2; } @Autowired @Qualifier("bean4") private Inner inner; public Inner getInner(){ return inner; } } @Slf4j static class Bean2{ public Bean2(){ log.info("构造 Bean2"); } } }
补充:使用@Bean注解将 组件注入到IOC容器里面,bean ID 默认就是类首字母小写,也可以用@Bean("里面指定Beanid")
2、解决方案一:使用@Qualifier("bean4")按bean的名称指定导入哪个Bean
成功取到Bean4取到
3、解决方案二:使用@Primary指定Bean的优先级
优先注入的是Bean3
4、解决方案三:使用@Autowired 但是成员变量 写上Bean的 id
优先注入Bean4
5、解决方案四:使用 @Resource(name = "bean3") name属性写Beanid
成功取到
本文作者:KwFruit
本文链接:https://www.cnblogs.com/mangoubiubiu/p/16079593.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
Spring
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步