天天看點

盤點Spring中Bean的注入方式

背景

        Spring中,我們總是通過IOC肆無忌憚的去擷取Bean對象,本着飲水思源的道理,我們來針對Bean注入的各種姿勢進行詳細分析。其實重點還有一個,面試的時候我很喜歡提這個問題,Spring的Bean注入方式你了解哪些?而非Spring的Bean擷取方式。

盤點Spring中Bean的注入方式

1. XML注入

        XML注入是一種最原生的注入方式,一個XML配置檔案,一個Bean配置對象,即可在Spring容器中注入一個Bean。

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--通過反射機制生成 id與name字段指派則調用了 set 與 get 方法-->
    <bean id="xmlUser" class="com.yiang.code.bean.entity.User">
        <property name="id" value="10"/>
        <property name="name" value="yiang"/>
    </bean>
</beans>
           

        以上代碼則代表在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的注入方式

6.  ImportSelector 接口 導入選擇器

        通過手寫類實作ImportSelector接口,并且注入到Spring容器,可實作自定義去注入對象,實則在前面@EnableAsync時,指向的AsyncConfigurationSelector類就是采用了這種方式進行導包,通過實作ImportSelector(基類),然後實作selectImports方法,去傳回對應的類名注入到Spring容器。

盤點Spring中Bean的注入方式

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<MyFactoryBeanEntity> {

    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的注入方式