Java開發學習(十)----基於註解開發定義bean

2022-07-11 06:49:26

一、環境準備

先來準備下環境:

  • 建立一個Maven專案

  • pom.xml新增Spring的依賴

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>
    </dependencies>
  • resources下新增applicationContext.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <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">
        <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
    </beans>
  • 新增BookDao、BookDaoImpl、BookService、BookServiceImpl類

    public interface BookDao {
        public void save();
    }
    public class BookDaoImpl implements BookDao {
        public void save() {
            System.out.println("book dao save ..." );
        }
    }
    public interface BookService {
        public void save();
    }
    ​
    public class BookServiceImpl implements BookService {
        public void save() {
            System.out.println("book service save ...");
        }
    }
    ​
  • 建立執行類App

    public class App {
        public static void main(String[] args) {
            ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
            BookDao bookDao = (BookDao) ctx.getBean("bookDao");
            bookDao.save();
        }
    }

最終建立好的專案結構如下:

二、註解開發定義bean

在上述環境的基礎上,我們來看一看Spring是如何通過註解實現bean的定義開發?

步驟1:刪除原XML設定

將組態檔中的<bean>標籤刪除掉

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>

步驟2:Dao上新增註解

在BookDaoImpl類上新增@Component註解

@Component("bookDao")
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ..." );
    }
}

注意:@Component註解不可以新增在介面上,因為介面是無法建立物件的。

XML與註解設定的對應關係:

步驟3:設定Spring的註解包掃描

為了讓Spring框架能夠掃描到寫在類上的註解,需要在組態檔上進行包掃描

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <context:component-scan base-package="com.itheima"/>
</beans>

說明:

component-scan

  • component:元件,Spring將管理的bean視作自己的一個元件

  • scan:掃描

base-package指定Spring框架掃描的包路徑,它會掃描指定包及其子包中的所有類上的註解。

  • 包路徑越多[如:com.itheima.dao.impl],掃描的範圍越小速度越快

  • 包路徑越少[如:com.itheima],掃描的範圍越大速度越慢

  • 一般掃描到專案的組織名稱即Maven的groupId下[如:com.itheima]即可。

步驟4:執行程式

執行App類檢視列印結果

步驟5:Service上新增註解

在BookServiceImpl類上也新增@Component交給Spring框架管理

@Component
public class BookServiceImpl implements BookService {
    private BookDao bookDao;
​
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
​
    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
}

步驟6:執行程式

在App類中,從IOC容器中獲取BookServiceImpl對應的bean物件,列印

public class App {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
        System.out.println(bookDao);
        //按型別獲取bean
        BookService bookService = ctx.getBean(BookService.class);
        System.out.println(bookService);
    }
}

列印觀察結果,兩個bean物件都已經列印到控制檯

說明:

  • BookServiceImpl類沒有起名稱,所以在App中是按照型別來獲取bean物件

  • @Component註解如果不起名稱,會有一個預設值就是當前類名首字母小寫,所以也可以按照名稱獲取,如

    BookService bookService = (BookService)ctx.getBean("bookServiceImpl");
    System.out.println(bookService);

對於@Component註解,還衍生出了其他三個註解@Controller@Service@Repository

通過檢視原始碼會發現:

這三個註解和@Component註解的作用是一樣的,為什麼要衍生出這三個呢?

方便我們後期在編寫類的時候能很好的區分出這個類是屬於表現層業務層還是資料層的類。

知識點1:@Component等

名稱 @Component/@Controller/@Service/@Repository
型別 類註解
位置 類定義上方
作用 設定該類為spring管理的bean
屬性 value(預設):定義bean的id

三、純註解開發模式

上面已經可以使用註解來設定bean,但是依然有用到組態檔,在組態檔中對包進行了掃描,Spring在3.0版已經支援純註解開發

  • Spring3.0開啟了純註解開發模式,使用Java類替代組態檔,開啟了Spring快速開發賽道

具體如何實現?

3.1 思路分析

實現思路為:

  • 將組態檔applicationContext.xml刪除掉,使用類來替換。

3.2 實現步驟

步驟1:建立設定類

建立一個設定類SpringConfig

public class SpringConfig {
}
​
步驟2:標識該類為設定類

在設定類上新增@Configuration註解,將其標識為一個設定類,替換applicationContext.xml

@Configuration
public class SpringConfig {
}
步驟3:用註解替換包掃描設定

在設定類上新增包掃描註解@ComponentScan替換<context:component-scan base-package=""/>

@Configuration
@ComponentScan("com.itheima")
public class SpringConfig {
}
步驟4:建立執行類並執行

建立一個新的執行類AppForAnnotation

public class AppForAnnotation {
​
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
        System.out.println(bookDao);
        BookService bookService = ctx.getBean(BookService.class);
        System.out.println(bookService);
    }
}

執行AppForAnnotation,可以看到兩個物件依然被獲取成功

至此,純註解開發的方式就已經完成了,主要內容包括:

  • Java類替換Spring核心組態檔

  • @Configuration註解用於設定當前類為設定類

  • @ComponentScan註解用於設定掃描路徑,此註解只能新增一次,多個資料請用陣列格式

    @ComponentScan({com.itheima.service","com.itheima.dao"})
  • 讀取Spring核心組態檔初始化容器物件切換為讀取Java設定類初始化容器物件

    //載入組態檔初始化容器
    ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    //載入設定類初始化容器
    ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);

知識點1:@Configuration

名稱 @Configuration
型別 類註解
位置 類定義上方
作用 設定該類為spring設定類
屬性 value(預設):定義bean的id

知識點2:@ComponentScan

名稱 @ComponentScan
型別 類註解
位置 類定義上方
作用 設定spring設定類掃描路徑,用於載入使用註解格式定義的bean
屬性 value(預設):掃描路徑,此路徑可以逐層向下掃描

四、小結

  • @Component、@Controller、@Service、@Repository這四個註解

  • applicationContext.xml中<context:component-san/>的作用是指定掃描包路徑,註解為@ComponentScan

  • @Configuration標識該類為設定類,使用類替換applicationContext.xml檔案

  • ClassPathXmlApplicationContext是載入XML組態檔

  • AnnotationConfigApplicationContext是載入設定類