spring 注册Bean的好几种方法

1. @Bean

通过在类级别上用@Configuration注解,方法上用@Bean注解显式注入Bean 。
类似xml配置中通过<beans><bean><bean></beans>来显式注入Bean。

如果被@Bean注解的方法中有参数,那么这些参数一定是存在于spring容器中的Bean,可以进行依赖注入。

方法中参数依赖注入规则如下:methods-inter-dependency相关文章

  • 通过类型注入
  • 通过Bean的名称注入
  • 通过Bean的名称和@qulifier(“Bean的名称”) 匹配来注入
  • 通过双方使用@qualifier进行匹配来注入

这里写图片描述

2. 实现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
     */
    public void registerBeanDefinitions(
            AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);

}
  1. 通过实现ImportBeanDefinitionRegistrar(导入Bean定义的注册员)接口,且通过@Configuration注解标记类。
  2. 重写registerBeanDefinitions方法,通过BeanDefinitionRegistry 注册Bean定义。这就是一个完整的注册员(ImportBeanDefinitionRegistrar)通过注册表(BeanDefinitionRegistry )注册Bean的流程。

当然其中ImportBeanDefinitionRegistrar的registerBeanDefinitions方法调用是在spring容器初始化的时候完成的,spring通过@Configuration注解类获取相关配置类信息ConfigurationClass.java,ConfigurationClass类中

private final Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> importBeanDefinitionRegistrars =
            new LinkedHashMap<ImportBeanDefinitionRegistrar, AnnotationMetadata>();

这里写图片描述

这一段代码就是存储实现importBeanDefinitionRegistrar 接口的实例,用于解析注册配置的Bean定义,最后在有spring容器生成Bean。

一般用法:因为要重写registerBeanDefinitions方法,registerBeanDefinitions方法的参数为importingClassMetadata和beanDefinitionRegistry 。所以可以通过importingClassMetadata获取注解中的属性值,再通过beanDefinitionRegistry 注册Bean定义。那么就可以在注解上通过@Import导入实现了ImportBeanDefinitionRegistrar 接口的配置类。

例子:

@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(SomeThingConfigRegistrar.class)
public @interface EnableSomeThing{

     String value() default "";
}
public class SomeThingConfigRegistrar implements ImportBeanDefinitionRegister{
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

        AnnotationAttributes attributes = AnnotationAttributes.fromMap(
                importingClassMetadata.getAnnotationAttributes(EnableSomeThing.class.getName()));

        ......
        //通过attributes对BeanDefinition进行填充,如构造器参数
        //通过注册表register进行Bean定义注册

    }
}

实现ImportBeanDefinitionRegistrar接口后遇到的问题:加载顺序,enviroment 依赖注入(通过实现EnvironmentAware接口),registerBeanDefinition,的顺序

3.ImportSelector

4. @Component,@Service,@Controller,@Repository

…不解释

猜你喜欢

转载自blog.csdn.net/canyanruxue/article/details/81475473