将 Bean 放入 Spring 容器中的五种方式
阅读本文大概需要 5 分钟。
来自:blog.csdn.net/weixin_43741092/article/details/120176466
1、@Configuration + @Bean
@Configurationpublic class MyConfiguration { @Bean public Person person() { Person person = new Person(); person.setName("spring"); return person; }}
2、@Componet + @ComponentScan
@Componentpublic class Person { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + '}'; }} @ComponentScan(basePackages = "com.springboot.initbean.*")public class Demo1 { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class); Person bean = applicationContext.getBean(Person.class); System.out.println(bean); }}
Person{name='null'}
3、@Import注解导入
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Import { /** * 用于导入一个class文件 * {@link Configuration @Configuration}, {@link ImportSelector}, * {@link ImportBeanDefinitionRegistrar}, or regular component classes to import. */ Class<?>[] value(); }
3.1 @Import直接导入类
public class Person { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + '}'; }}/*** 直接使用@Import导入person类,然后尝试从applicationContext中取,成功拿到**/@Import(Person.class)public class Demo1 { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class); Person bean = applicationContext.getBean(Person.class); System.out.println(bean); }}
注意:我们的Person类上 就不需要任何的注解了,直接导入即可。
3.2 @Import + ImportSelector
@Import(MyImportSelector.class)public class Demo1 { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class); Person bean = applicationContext.getBean(Person.class); System.out.println(bean); }} class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { return new String[]{"com.springboot.pojo.Person"}; }}
3.3 @Import + ImportBeanDefinitionRegistrar
@Import(MyImportBeanDefinitionRegistrar.class)public class Demo1 { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class); Person bean = applicationContext.getBean(Person.class); System.out.println(bean); }} class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { // 构建一个beanDefinition, 关于beanDefinition我后续会介绍,可以简单理解为bean的定义. AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Person.class).getBeanDefinition(); // 将beanDefinition注册到Ioc容器中. registry.registerBeanDefinition("person", beanDefinition); }}
3.4 @Import + DeferredImportSelector
@Import(MyDeferredImportSelector.class)public class Demo1 { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class); Person bean = applicationContext.getBean(Person.class); System.out.println(bean); }}class MyDeferredImportSelector implements DeferredImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { // 也是直接将Person的全限定名放进去 return new String[]{Person.class.getName()}; }}
4、使用FactoryBean接口
@Configurationpublic class Demo1 { @Bean public PersonFactoryBean personFactoryBean() { return new PersonFactoryBean(); } public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class); Person bean = applicationContext.getBean(Person.class); System.out.println(bean); }} class PersonFactoryBean implements FactoryBean<Person> { /** * 直接new出来Person进行返回. */ @Override public Person getObject() throws Exception { return new Person(); } /** * 指定返回bean的类型. */ @Override public Class<?> getObjectType() { return Person.class; }}
5、使用 BeanDefinitionRegistryPostProcessor
public class Demo1 { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); MyBeanDefinitionRegistryPostProcessor beanDefinitionRegistryPostProcessor = new MyBeanDefinitionRegistryPostProcessor(); applicationContext.addBeanFactoryPostProcessor(beanDefinitionRegistryPostProcessor); applicationContext.refresh(); Person bean = applicationContext.getBean(Person.class); System.out.println(bean); }} class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Person.class).getBeanDefinition(); registry.registerBeanDefinition("person", beanDefinition); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { }}
小结
-
@Configuration + @Bean -
@ComponentScan + @Component -
@Import 配合接口进行导入 -
使用FactoryBean。 -
实现BeanDefinitionRegistryPostProcessor进行后置处理。
推荐阅读:
面试 Dubbo ,却问我和 SpringCloud 有什么区别?
互联网初中高级大厂面试题(9个G) 内容包含Java基础、JavaWeb、MySQL性能优化、JVM、锁、百万并发、消息队列、高性能缓存、反射、Spring全家桶原理、微服务、Zookeeper......等技术栈!
⬇戳阅读原文领取! 朕已阅