盘点Spring中Bean的注入方式

背景

        Spring中,我们总是通过IOC肆无忌惮的去获取Bean对象,本着饮水思源的道理,我们来针对Bean注入的各种姿势进行详细分析。其实重点还有一个,面试的时候我很喜欢提这个问题,Spring的Bean注入方式你了解哪些?而非Spring的Bean获取方式。

盘点Spring中Bean的注入方式_第1张图片

1. XML注入

        XML注入是一种最原生的注入方式,一个XML配置文件,一个Bean配置对象,即可在Spring容器中注入一个Bean。



    
    
        
        
    

        以上代码则代表在spring容器中注入一个id名为user的对象。获取时通过 applicationContext.getBean("user", User.class); 获取即可。

2. @Bean注入

        @configuration + @Bean 注解,相当于XML注入方法的简化注解形式,一个配置类加上@configuration 注解,在类中使用@Bean注解注入对象接口。ID为方法名称

@Configuration
public class SpringTestConfig {
    @Bean
    public User user() {
        return new User(2, "yiang");
    }
}

        以上代码则表示在Spring容器中注入一个ID为2,名称为yiang的用户实体。关于Bean注解的其它说明可以参考该文章:偷窥Spring中的Bean加载。

3. @Conditional 条件判断

        @Bean的条件注入注解,与@Bean一起在对象注入时使用,可以通过@Conditional(WindowsCondition.class)指定条件处理类,处理类通过实现Condition接口,来进行相关的逻辑判断,以下代码则表示,如果操作系统为Windows10的情况下,才会放行将该Bean注入到Spring容器中。 

public class WindowsCondition implements Condition {

    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Environment environment = context.getEnvironment();
        String property = environment.getProperty("os.name");
        return "Windows 10".equals(property);
    }
}

4. @Import 导入

        @Import导入注解,使用在类头,包含一个Class[]的数组参数,可以传入多个类,一般更多用于外部jar对象导入,导入的对象ID为其全路径名,与@Bean注解的区别是@Bean的导入默认为方法名或者是首字母小写的驼峰。使用方法如下

@Import({PayEntity.class})
public class SpringTestConfig {

        表示注入配置的PayEntity类对象,注入后的ID如下:

com.yiang.code.entity.PayEntity

5. @EnableXXX 支持..导入

        @EnableXXX是大部分框架的导包实现,很凸显的栗子就是@EnableEureka(注册中心)、@EnableFeignClients(Feign客户端)、@EnableAsync(异步注解)。

        我们翻看到@EnableAsync 异步注解源码中,实际上在里面的处理还是通过调用的@Import注解,那么也就是说,@EnableXXX、注解实际上就是对@Import注解的一个封装。使用时在配置导入的时候,仅仅只需要使用一个@Enablexxx即可,无需指定导入某个类。更加简单、整洁。

盘点Spring中Bean的注入方式_第2张图片

6.  ImportSelector 接口 导入选择器

        通过手写类实现ImportSelector接口,并且注入到Spring容器,可实现自定义去注入对象,实则在前面@EnableAsync时,指向的AsyncConfigurationSelector类就是采用了这种方式进行导包,通过实现ImportSelector(基类),然后实现selectImports方法,去返回对应的类名注入到Spring容器。

盘点Spring中Bean的注入方式_第3张图片

 

7. ImportBeanDefinitionRegistrar接口  自定义Bean注册器

          通过手写类实现ImportBeanDefinitionRegistrar接口,并且注入到Spring容器,注入形式和@ImportSelector接口无差距,通过实现接口方法即可。以下代码则代表注入RegisterEntity

类到容器中,ID为registerEntity。

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(RegisterEntity.class);
        registry.registerBeanDefinition("registerEntity", rootBeanDefinition);
    }
}

8. FactoryBean接口 实例注册工厂

        这里需要注意的是FactoryBean接口 与BeanFactory的区别,本接口是注册Bean对象的,而BeanFactory接口则是获取Bean对象。

        实现方式也比较简单,isSingleton方法决定是否单例,默认不会强制实现,是false,实现改为true则是单例模式,其它就是返回对应的对象与类实例。

public class MyFactoryBean implements FactoryBean {

    public MyFactoryBeanEntity getObject() {
        return new MyFactoryBeanEntity();
    }

    public Class getObjectType() {
        return MyFactoryBeanEntity.class;
    }

    public boolean isSingleton() {
        return true;
    }
}

        注入时可以使用@Bean注册该类,亦可以使用@Import导入

@Bean
public MyFactoryBean myFactoryBean() {
    return new MyFactoryBean();
}

9. @Component组件注解 @Service、@Repository、@Controller

        正常项目开发架构中,用的最多的也就是这几个注解了。@Repository代表Mapper文件Dao层,@Service代表业务逻辑层,@Controller代表控制层,这个需要注意的是@RestController并非Spring包自带的注解。所以不在此说明。实际上进行代码分组的三个注解核心都是依赖的@Component注解。只做区分,其实内部并无差距。

总结

        以上即为9种Spring中Bean的注入方式, 很多方式其实属于大同小异,可以根据需求灵活运用。我们亦可以在实际项目中选择自己喜欢的方式,保证其适用性与合理性即可。

盘点Spring中Bean的注入方式_第4张图片

你可能感兴趣的:(Spring,Java后端,Javabean注入的方式,spring注入bean对象,spring,bean,Spring有哪几种注入方式,spring常用注解)