SpringBoot-将Bean放入容器的五种方式

1、@Configuration + @Bean

复制代码
@Configuration
public class MyConfiguration {
    @Bean
    public Person person() {
        Person person = new Person();
        person.setName("spring");
        return person;
    }
}

2、@Componet + @ComponentScan

复制代码
@Component
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 + '\'' +
                '}';
    }
}
 
@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);
    }
}

3、@Import注解导入

@import注解源码

复制代码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
 
    /**   * 用于导入一个class文件     * {@link Configuration @Configuration}, {@link ImportSelector},     * {@link ImportBeanDefinitionRegistrar}, or regular component classes to import.     */
    Class<?>[] value();
 
}

3.1、直接使用@import注解导入类

然后自动的就被放置在IOC容器中了。

复制代码
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);
    }
}

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

bean的定义(bean的元数据),也是需要放在IOC容器中进行管理的,先有bean的元数据,

applicationContext再根据bean的元数据去创建Bean。

复制代码
@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

DeferredImportSelector 它是 ImportSelector 的子接口,所以实现的方法和第二种无异。

只是Spring的处理方式不同,它和Spring Boot中的自动导入配置文件 延迟导入有关

复制代码
@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接口

FactoryBean, 后缀为bean,那么它其实就是一个bean,

BeanFactory,顾名思义 bean工厂,它是IOC容器的顶级接口

复制代码
@Configuration
public 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

等beanDefinition加载完毕之后,对beanDefinition进行后置处理,

可以在此进行调整IOC容器中的beanDefinition,从而干扰到后面进行初始化bean。

复制代码
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 {
 
    }
}
相关推荐
普修罗双战士14 小时前
项目设计-文章系统发布文章完整前后端设计
java·数据库·vue.js·spring boot·git·intellij-idea
StockTV14 小时前
新加坡股票API 实时行情、K 线及指数数据
android·java·spring boot·后端·区块链
RuoyiOffice14 小时前
SpringBoot+Vue3 企业云盘系统设计:文件上传+共享权限+收藏分类+5GB空间控制——从“网盘孤岛”到“企业知识底座”
spring boot·uni-app·vue·文件管理·云盘·网盘·ruoyioffice
bitt TRES1 天前
springboot与springcloud对应版本
java·spring boot·spring cloud
2301_771717211 天前
Spring Boot 自动配置核心注解
java·spring boot·mybatis
❀͜͡傀儡师1 天前
Claude Code 命令大全:从入门到精通的完整指南
spring boot·claude code
kybs19911 天前
springboot租车系统--附源码68701
java·hadoop·spring boot·python·django·asp.net·php
过期动态1 天前
MySQL中的约束
android·java·数据库·spring boot·mysql
wxin_VXbishe1 天前
springboot新能源车充电站管理系统小程序-计算机毕业设计源码29213
java·c++·spring boot·python·spring·django·php
代码漫谈1 天前
一文学习 SpringBoot 的 application.yml 配置,基于 Spring Boot 3.2.x
java·spring boot·spring·配置文件