spring注解开发——向IOC容器注册组件的几种方式

本文详细介绍五种向Spring IOC容器注册组件的方法:配置包扫描、使用@Bean、@Import注解、ImportSelector接口及ImportBeanDefinitionRegistrar接口。每种方法都有其特点,适合不同场景。

向IOC容器注册组件的几种方式

  • 第一种大家都常见,配置包扫描+类上注解(@Component, @Controller, @Service, @Repository, @Resource)

    也就是这样:

    // 配置类
    @Configuration
    @ComponentScan("com.example.demo.bean")
    public class AnnotationConfigTestImport {
    }
    
    // bean
    package com.example.demo.bean;
    
    import org.springframework.stereotype.Component;
    
    @Component
    public class Dog {
        public Dog() {
            System.out.println("===> dog bean created...");
        }
    }
    

    这样凡是扫描的包下带有以上注解的都会被注册到IOC容器。但是缺点也显而易见:不能注册第三方包中的类

  • 第二种,使用@Bean,像这样:

    @Configuration
    // @ComponentScan("com.example.demo.bean")
    public class AnnotationConfigTestImport {
    
        @Bean
        public Cat cat() {
            return new Cat();
        }
    
        @Bean
        public Dog dog() {
            return new Dog();
        }
    }
    

    这种方式可以随意注册任何组件到容器,但是麻烦…每增加一个组件,我们都要在配置类里增加一个@Bean

  • 第三种,在配置类上使用@Import注解,我们先看看@Import源码:

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Import {
    
    	/**
    	 * {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar}
    	 * or regular component classes to import.
    	 */
    	Class<?>[] value();
    }
    

    可以看到@Import需要我们传一个Class数组,也就是我们要注册到容器的类。那我们就这样用:

    @Configuration
    // @ComponentScan("com.example.demo.bean")
    @Import({Cat.class, Dog.class})
    public class AnnotationConfigTestImport {
    
    }
    

    这种比上一种方式更加简洁一些,能少写一些代码

  • 第四种,使用ImportSelector接口,我们先看看什么是ImportSelector

    public interface ImportSelector {
    
    	/**
    	 * Select and return the names of which class(es) should be imported based on
    	 * the {@link AnnotationMetadata} of the importing @{@link Configuration} class.
    	 */
    	String[] selectImports(AnnotationMetadata importingClassMetadata);
    }
    

    接口里面就一个方法,从方法的注释上我们可以看到,返回一个包含类名的数组,这些类将被注册到容器。那我们写一个ImportSelector的实现类,返回我们要注册到容器的bean:

    public class MyImportSelector implements ImportSelector {
        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
            return new String[]{"com.example.demo.bean.Windows"};
        }
    }
    

    然后在配置类中import我们写的selector即可,像这样:

    @Configuration
    @Import({Cat.class, Dog.class, MyImportSelector.class})
    public class AnnotationConfigTestImport {
    
    }
    
  • 第五种,使用ImportBeanDefinitionRegistrar接口,我们看看这个接口是啥:

    public interface ImportBeanDefinitionRegistrar {
    
    	/**
    	 * Register bean definitions as necessary based on the given annotation metadata of
    	 * the importing {@code @Configuration} class.
    	 * <p>Note that {@link BeanDefinitionRegistryPostProcessor} types may <em>not</em> be
    	 * registered here, due to lifecycle constraints related to {@code @Configuration}
    	 * class processing.
    	 * @param importingClassMetadata annotation metadata of the importing class
    	 * @param registry current bean definition registry
    	 */
    	void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);
    }
    

    我们看到这个接口有个registerBeanDefinitions()方法,方法的参数里有个BeanDefinitionRegistry,这个就是我们注册bean的类,我们可以使用这个类来注册我们的组件。现在我们来实现这个类:

    public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Linux.class);
    
            registry.registerBeanDefinition("linux", rootBeanDefinition);
        }
    }
    

    然后在配置类import这个类即可向容器中注册名字为linux的bean。

    @Configuration
    // @ComponentScan("com.example.demo.bean")
    @Import({Cat.class, Dog.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
    public class AnnotationConfigTestImport {
    }
    

以上就是我学习到的注册组件的几种方式,每种都简单的介绍了一下,实际上我们还可以做更多的操作,比如第四,第五种方式,在注册bean的时候我们还可以添加更多的逻辑,这个大家下去自行探索吧~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值