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


    1、@Configuration + @Bean

    1. @Configuration
    2. public class MyConfiguration {
    3. @Bean
    4. public Person person() {
    5. Person person = new Person();
    6. person.setName("spring");
    7. return person;
    8. }
    9. }

    2、@Componet + @ComponentScan

    1. @Component
    2. public class Person {
    3. private String name;
    4. public String getName() {
    5. return name;
    6. }
    7. public void setName(String name) {
    8. this.name = name;
    9. }
    10. @Override
    11. public String toString() {
    12. return "Person{" +
    13. "name='" + name + '\'' +
    14. '}';
    15. }
    16. }
    17. @ComponentScan(basePackages = "com.springboot.initbean.*")
    18. public class Demo1 {
    19. public static void main(String[] args) {
    20. AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class);
    21. Person bean = applicationContext.getBean(Person.class);
    22. System.out.println(bean);
    23. }
    24. }

    3、@Import注解导入

    @import注解源码

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

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

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

    1. public class Person {
    2. private String name;
    3. public String getName() {
    4. return name;
    5. }
    6. public void setName(String name) {
    7. this.name = name;
    8. }
    9. @Override
    10. public String toString() {
    11. return "Person{" +
    12. "name='" + name + '\'' +
    13. '}';
    14. }
    15. }
    16. /*** 直接使用@Import导入person类,然后尝试从applicationContext中取,成功拿到**/
    17. @Import(Person.class)
    18. public class Demo1 {
    19. public static void main(String[] args) {
    20. AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class);
    21. Person bean = applicationContext.getBean(Person.class);
    22. System.out.println(bean);
    23. }
    24. }

    3.2 @Import + ImportSelector

    1. @Import(MyImportSelector.class)
    2. public class Demo1 {
    3. public static void main(String[] args) {
    4. AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class);
    5. Person bean = applicationContext.getBean(Person.class);
    6. System.out.println(bean);
    7. }
    8. }
    9. class MyImportSelector implements ImportSelector {
    10. @Override
    11. public String[] selectImports(AnnotationMetadata importingClassMetadata) {
    12. return new String[]{"com.springboot.pojo.Person"};
    13. }
    14. }

    3.3 @Import + ImportBeanDefinitionRegistrar

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

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

     

    1. @Import(MyImportBeanDefinitionRegistrar.class)
    2. public class Demo1 {
    3. public static void main(String[] args) {
    4. AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class);
    5. Person bean = applicationContext.getBean(Person.class);
    6. System.out.println(bean);
    7. }
    8. }
    9. class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    10. @Override
    11. public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    12. // 构建一个beanDefinition, 关于beanDefinition我后续会介绍,可以简单理解为bean的定义.
    13. AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Person.class).getBeanDefinition();
    14. // 将beanDefinition注册到Ioc容器中.
    15. registry.registerBeanDefinition("person", beanDefinition);
    16. }
    17. }

    3.4 @Import + DeferredImportSelector

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

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

    1. @Import(MyDeferredImportSelector.class)
    2. public class Demo1 {
    3. public static void main(String[] args) {
    4. AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class);
    5. Person bean = applicationContext.getBean(Person.class);
    6. System.out.println(bean);
    7. }
    8. }
    9. class MyDeferredImportSelector implements DeferredImportSelector {
    10. @Override
    11. public String[] selectImports(AnnotationMetadata importingClassMetadata) {
    12. // 也是直接将Person的全限定名放进去
    13. return new String[]{Person.class.getName()};
    14. }
    15. }

    4、使用FactoryBean接口

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

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

    1. @Configuration
    2. public class Demo1 {
    3. @Bean
    4. public PersonFactoryBean personFactoryBean() {
    5. return new PersonFactoryBean();
    6. }
    7. public static void main(String[] args) {
    8. AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class);
    9. Person bean = applicationContext.getBean(Person.class);
    10. System.out.println(bean);
    11. }
    12. }
    13. class PersonFactoryBean implements FactoryBean<Person> {
    14. /** * 直接new出来Person进行返回. */
    15. @Override
    16. public Person getObject() throws Exception {
    17. return new Person();
    18. }
    19. /** * 指定返回bean的类型. */
    20. @Override
    21. public Class<?> getObjectType() {
    22. return Person.class;
    23. }
    24. }

    5、使用 BeanDefinitionRegistryPostProcessor

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

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

    1. public class Demo1 {
    2. public static void main(String[] args) {
    3. AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
    4. MyBeanDefinitionRegistryPostProcessor beanDefinitionRegistryPostProcessor = new MyBeanDefinitionRegistryPostProcessor();
    5. applicationContext.addBeanFactoryPostProcessor(beanDefinitionRegistryPostProcessor);
    6. applicationContext.refresh();
    7. Person bean = applicationContext.getBean(Person.class);
    8. System.out.println(bean);
    9. }
    10. }
    11. class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    12. @Override
    13. public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    14. AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Person.class).getBeanDefinition();
    15. registry.registerBeanDefinition("person", beanDefinition);
    16. }
    17. @Override
    18. public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    19. }
    20. }

  • 相关阅读:
    zabbix的rpm包部署
    网络安全实验环境搭建
    KDD 2022 | 深度图神经网络中的特征过相关:一个新的视角
    【uniapp】使用Vant组件van-toast与van-dialog
    PAT甲级打卡-1005-1010
    基础 | java - [强引用、软引用、弱引用、虚引用]
    golang中的网络轮询器netpoll源码解析
    RabbitMq学习笔记
    企业低成本万能架构
    C++ 邮件槽ShellCode跨进程传输
  • 原文地址:https://blog.csdn.net/xcg340123/article/details/136162985