Spring核心系列之Bean的注入

我又不是架構師發表於2018-01-08

Spring核心系列之Bean的注入

Hello,大家好,上兩篇博文給大家分享了Spring容器的建立,以及Bean的生命週期,今天這一篇給大家講解Bean的注入,就是Bean的一些注入方式,配置方式,然後再講一下作者的一點使用經驗,其實這一篇也是比較基礎的東西,好了,老套路,文章結構:

  1. 基於XML的配置
  2. 基於註解的配置
  3. 基於Spring config 的配置
  4. 幾種配置方式的混合使用

1. 基於XML的配置

單單這一小節,如果往細了說,一篇博文都是不夠的,因為知識點比較多,比較雜,而且,絕大部分都是一輩子用不上的。所以我想了想,還是直接乾脆直接的上重點,很多不用的能提就提一下。

1.1 DTD格式

Spring的XML配置檔案是DTD格式的,很多人其實對這個XML的開頭一些配置都不理,我這裡還是提一下:

Spring核心系列之Bean的注入

Beans標籤的格式:
<Beans xmlns屬性 xmlns屬性 ... xsi屬性>

  • xmlns屬性定義名稱空間,名稱空間就是所有檔案定義bean時帶的字首,像aop:config,這個標籤的aop就是aop名稱空間 ,沒有加名稱空間,就是預設的名稱空間.

  • xsi屬性是根據全限定名稱指定格式檔案xsd的.

  • xmlns屬性的格式:xmlns:名稱空間="名稱空間的全限定名(可以隨意命名,命為123都可以)"

  • xsd 格式: "xmlns定義的名稱空間"+"空格"+"xsd檔案"

說下指定xsd的作用:當你敲下 的前半段<bea,它個你提示出全部的 。 其實這個就是ide根據xsd檔案幫你列出來的。

1.2 定義Bean

在xml檔案裡定義Bean,賊簡單的一個:

<bean id="stu" class="com.zdy.Student" >
    <property name="name"><value>張三</value></property>
</bean>
複製程式碼

是根據setter方法注入的。大家不要在看什麼根據建構函式注入屬性了。西壩,博主這麼多年都沒有過這種操作。都是根據setter注入的。 然後說一下,XML裡面有一些特殊字元,要使用轉義序列代替,我給個表格:

Spring核心系列之Bean的注入

至於網上說的還有一種:<![CDATA[]]>的搞法,大家忽略掉。一是不方便,二是不支援p名稱空間。待會會說到p名稱空間.

上面的例子是注入的常量,然後提下bean之間的相互依賴:

<bean id="car" calss="..." />
<bean id="boss" class="..." >
    <property name="car">
        <ref bean="car"></ref>
    </property>
</bean>
複製程式碼

其他的一些什麼集合注入,級聯注入,我就不提了,根本沒地用。

1.3 xml簡化配置之p名稱空間

上面的配置大家可以看到,賊複雜,而且在配置bean之間的相互依賴關係時還要使用ref標籤。現在來給大家說下簡化配置方式,和自動注入. p名稱空間是Spring2.5之後提供的,目的就是為了簡化配置,看下效果:

//使用前
<bean id="stu" class="com.zdy.Student" >
    <property name="name"><value>張三</value></property>
</bean>
//使用後
<bran id="stu" class="..." p:name="張三" />
複製程式碼

然後說下格式:

  • 對於字面常量: p:屬性名=".."
  • 對於引用bean的屬性: p:屬性名-ref="..."

然後提一下自動注入:大家可以看到如果使用ref標籤來注入bean依賴,程式設計師會死掉的。比如一個Controller層的Bean,依賴的Service層的Bean可能有10幾個。一個個的配置了寫。肯定是不行的。所以自動注入就出來了。@Autowired註解,後面會講。這裡只是提一下.

然後提一下,標籤,用於匯入多個xml配置檔案到一個xml配置檔案中.

2. 基於註解的配置

上面可以看到,想把Bean注入到Spring容器中,可以使用標籤,然後注入一些屬性什麼的。並且bean之間的引用關係可以使用ref標籤。其實工作中這種操作基本沒有公司會採納的。因為太麻煩了,由於是配到ref標籤時,真的會死人的。工作中,對於我們自己建立的bean,肯定是會使用註解的方式來配置的,具體使用方法:

  1. 在xml檔案中或者Java config類中加上掃描路徑,這裡說下xml的配置:
<context:component-scan base-package="...">
複製程式碼
  1. 我們自己寫的bean上面加上@Component,@Controller,@Service,@Dao
@Component
public class UerDao {
    ...
}
複製程式碼

這樣,我們的UserDao就注入到了Spring容器中。那麼這種配置方式是如何解決相互依賴關係呢?@AutoWired

@Controller
public class UserController{
    @Autoired
    private UserService userService;
    ...
}
複製程式碼

@Autoired會自動根據型別來把Bean注入進來。這多簡單呢?至於一些其他的引數,我就不擴充套件了。

3. 基於Spring config 的配置

直接給一個Config類:

@Configuration
public class UserJedisConfig {

    @Bean
    public CacheManager cacheManager(final RedisTemplate redisTemplate) {
        return new RedisCacheManager(redisTemplate);
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate2(final RedisConnectionFactory factory) {
        final RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new RedisObjectSerializer());
        template.afterPropertiesSet();
        return template;
    }
}
複製程式碼

@Configuration 內部包含了@Component,說白了,當這個Bean加入到Spring容器中時,它內部標註了@Bean的方法返回的Bean都會放到Spring容器中。 具體的語法我不多說了。 @Configuration類想加入到Spring容器中有三種方式,一種是在xml裡通過<context:component-scan base-package="...">掃描。一種是通過其他的Config類加上@Componentscan註解,作用是一樣的,掃描配置路徑下的POJO ,最後一種是在建立容器的時候直接指定這個config類,而不是xml配置檔案,前面的部落格講到過。

4. 幾種配置方式的混合使用

好了,其實想把Bean加入到Spring容器中的方法無非是以上三種。而且也都很基礎。我說下實際工作當中的一些小經驗:

  1. 註解大於xml配置。大家自己也可以感覺到註解的方便。
  2. 自己寫的bean全部使用註解來注入到容器中。至於容器啟動的時候是使用xml檔案還是Config類,這都無所謂。只要加了自動掃描即可。
  3. 整合一些三方的框架(如Jedis),需要放入三方的bean到Spring容器中時,這時候沒辦法使用註解,可以使用xml檔案配置或者config類配置。

最後給一個比較圖,和使用場景圖:

Spring核心系列之Bean的注入
Spring核心系列之Bean的注入

最後說一下,作者遇到過的實際的這幾種方式的選擇:

  1. 之前在某家房地產公司用到的是"XML+註解",這種方式還是比較多見,比較傳統的。Web專案,容器啟動以來一個xml檔案,然後xml檔案中配置掃描的跟路徑,自己寫的Bean放在路徑下面並加上類似於@Componenet的註解,依賴關係依賴於@Autowired註解。如果引用了一些三方的框架,想使用一些框架自帶的Bean,就在xml中配置標籤加到容器裡面去。這是比較傳統的Spring容器使用方式。
  2. Spring boot,用過或者瞭解過Spring boot的小夥伴應該知道,Spring boot中是沒有xml檔案的,容器啟用依賴一個自帶的config類,這個config類會自動掃描跟路徑之下的,所以我們開發的類只要加上了@Component類似的註解都會被加入到容器當中。依賴一些三方的框架的Bean,一般情況下,Spring boot會有一些auto注入機制,自動根據配置的引數建立Bean並自動注入bean到容器中。開發者直接@Autowired就可以使用。特殊情況下才會自己寫一個config類來注入一下Spring boot沒有自帶的三方bean。為什麼用過Spring boot的小夥伴都覺得Spring boot比較簡潔呢?你想一想,如果你要使用Jedis,只需要pom引入即可。然後就直接@Autowired注入相應的bean,根本不需要配置。這也是Spring boot最最核心的一個特色。後期有機會講Spring boot時給大家分享這種自動注入是如何實現的。

結語

好了,其實這一小節比較簡單,大家可以看到,作者沒有講具體太細的使用方法,像@Autowired的一些屬性,@Configuration的一些語法什麼的,作者都是一筆帶過,給了個例子,因為作者覺得這一篇的重點應該是把握好這幾種注入Bean的機制,舉幾個例子:

  1. 開發者在自己的工程中看到了寫的bean被加上了@Component註解,要能知道這個bean是怎麼被加進來的(是xml掃描,還是config檔案掃描),
  2. 接到工程發現web工程竟然沒有Spring的XML主檔案。(這時候就要想到是不是通過Config類來啟動的容器)
  3. 開發者想加入一些三方的Bean到容器裡,是使用xml配置,還是使用config類配置。 好了,這一篇給大家分享完了,今天週一,大家鼓足幹勁,好好上班,賺錢過年回家。Over,Hava a good day .

相關文章