1. 程式人生 > 其它 >3、Spring IOC的註解使用

3、Spring IOC的註解使用

1、概述

  上篇文章中整理了通過XML檔案進行Bean或某些屬性的賦值,xml的方式在企業開發中已經過時了,這篇文章即為進階篇。介紹如何在bean上添加註解,快速的將bean註冊到ioc容器。

2、使用註解的方式註冊Bean到 IOC容器中

  如果想要將自定義的bean物件新增到IOC容器中,需要在類上新增某些註解 。

  Spring中包含4個主要的元件添加註解:

  @Controller:控制器,推薦給controller層新增此註解

  @Service:業務邏輯,推薦給業務邏輯層新增此註解

  @Repository:倉庫管理,推薦給資料訪問層新增此註解

  @Component:給不屬於以上基層的元件新增此註解

  注意:我們雖然人為的給不同的層新增不同的註解,但是在spring看來,可以在任意層新增任意註解。spring底層是不會給具體的層次驗證註解,這樣寫的目的只是為了提高可讀性,最偷懶的方式就是給所有想交由IOC容器管理的bean物件新增component註解

  使用註解需要如下步驟:

  1、新增上述四個註解中的任意一個

  2、新增自動掃描註解的元件,此操作需要依賴context名稱空間

  3、新增自動掃描的標籤context:component‐scan

  注意:當使用註解註冊元件和使用配置檔案註冊元件是一樣的,但是要注意:

  1、元件的id預設就是元件的類名首字元小寫,如果非要改名字的話,直接在註解中新增即可。如@Controller("userInfo")

  2、元件預設情況下都是單例的,如果需要配置多例模式的話,可以在註解下新增@Scope註解

  <!-- 定義自動掃描的基礎包:
    base‐package:指定掃描的基礎包,spring在啟動的時候會將基礎包及子包下所有加了註解的類都自動掃描進IOC容器-->
    <context:component-scan base-package="com.zhl"></context:component-scan>
package com.zhl.controller;

import org.springframework.stereotype.Controller;

@Controller
public class UserController { }
package com.zhl.service;

import org.springframework.stereotype.Service;

@Service
public class UserService {
}
package com.zhl.dao;

import org.springframework.stereotype.Repository;

@Repository
public class UserDao {
}

3、定義掃描包時要包含的類和不要包含的類

  當定義好基礎的掃描包後,在某些情況下可能要有選擇性的配置是否要註冊bean到IOC容器中,此時可以通過如下的方式進行配置。

  <!-- 定義自動掃描的基礎包:
    base‐package:指定掃描的基礎包,spring在啟動的時候會將基礎包及子包下所有加了注
    解的類都自動掃描進IOC容器-->
    <context:component-scan base-package="com.zhl.entity" use-default-filters="false">
        <!--當定義好基礎掃描的包之後,可以排除包中的某些類,使用如下的方式:
         type:表示指定過濾的規則
            annotation:按照註解進行排除,標註了指定註解的元件不要,expression表示要過濾的註解的全限定類名,該註解下的Bean全部排除
            assignable:指定排除某個具體的類,按照類排除,expression表示不註冊的具體類名-->
       <!-- <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->
        <!--<context:exclude-filter type="assignable" expression="com.zhl.entity.User"/>  -->

        <!--指定只掃描哪些元件,預設情況下是全部掃描的,所以此時要配置的話需要在component‐scan標籤中新增 use‐default‐filters="false"-->
        <!--<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->
        <context:include-filter type="assignable" expression="com.zhl.entity.User"/>
    </context:component-scan>

4、使用@AutoWired進行自動注入

  使用註解的方式實現自動注入,需要使用@AutoWired註解。

  注意:當使用AutoWired註解的時候,自動裝配的時候是根據型別實現的。

    a、如果只找到一個,則直接進行賦值,

    b、如果沒有找到,則直接丟擲異常,

    c、如果找到多個,那麼會按照變數名作為id繼續匹配,

      c.1、匹配上直接進行裝配

      c.2、如果匹配不上則直接報異常

package com.zhl.controller;

import com.zhl.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {
    /*
    使用@Autowired來實現自動注入
    bytype?  byname?
    ·預設優先根據型別去匹配
    ·如果匹配到多個型別則會按照名字匹配
    ·如果名又沒有匹配到則會報錯:
                    1.可以去修改屬性的名字對應bean的名字:userServiceImpl
                    2.可以去修改Bean的名字對應屬性的名字:@Service("userService")
                    3.可以通過@Qualifier設定屬性的名字(覆蓋) :@Qualifier("userServiceImpl")
                    4.可以通過@Primary 設定其中一個Bean為主要的自動注入Bean:@Primary
                    5.使用泛型作為自動注入限定符
     */
    @Autowired
    private UserService userService;

    public void getUser() {
        userService.getUser();
    }
}
package com.zhl.service;

import org.springframework.stereotype.Service;

@Service
public class UserService {

    public void getUser() {
        System.out.println("返回User");
    }
}

5、@AutoWired可以進行定義在方法上

  此註解不僅可以使 用在成員變數上,也可以使用在方法上。

package com.zhl.controller;

import com.zhl.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {
    /*
    使用@Autowired來實現自動注入
    bytype?  byname?
    ·預設優先根據型別去匹配
    ·如果匹配到多個型別則會按照名字匹配
    ·如果名又沒有匹配到則會報錯:
                    1.可以去修改屬性的名字對應bean的名字:userServiceImpl
                    2.可以去修改Bean的名字對應屬性的名字:@Service("userService")
                    3.可以通過@Qualifier設定屬性的名字(覆蓋) :@Qualifier("userServiceImpl")
                    4.可以通過@Primary 設定其中一個Bean為主要的自動注入Bean:@Primary
                    5.使用泛型作為自動注入限定符
     */
    @Autowired
    private UserService userService;

    public void getUser() {
        userService.getUser();
    }


    /**
     * @Autowired 也可以寫在構造器上面
     * ·預設優先根據引數型別去匹配
     * ·如果匹配到多個型別則會按照引數名字匹配
     */
     @Autowired
     public UserController(UserService userService) {
     this.userService = userService;
     }

    /**
     * @Autowired 也可以寫在方法上面
     * ·預設優先根據引數型別去匹配
     * ·如果匹配到多個型別則會按照引數名字匹配
     * @param userService
     * 當方法上有@AutoWired註解時:
     * 1、此方法在bean建立的時候會自動呼叫
     * 2、這個方法的每一個引數都會自動注入值
     */
     @Autowired
     public void createUserSerive(UserService userService){
        this.userService=userService;
     }
}

6、自動裝配的註解@AutoWired,@Resource

  在使用自動裝配的時候,除了可以使用@AutoWired註解之外,還可以使用@Resource註解,區別如下:

  a、@AutoWired:是spring中提供的註解,@Resource:是jdk中定義的 註解,依靠的是java的標準

  b、@AutoWired預設是按照型別進行裝配,預設情況下要求依賴的物件必須存在,@Resource預設是按照名字進行匹配的,同時可以指定name屬性。

  c、@AutoWired只適合spring框架,而@Resource擴充套件性更好

  d、@Autowired如果需要按照名稱匹配需要和@Qualifier一起使用