1. 程式人生 > 實用技巧 >【Spring】08 後續的學習補充 vol2

【Spring】08 後續的學習補充 vol2

1、【純註解配置實現】

首先實現純註解配置的第一件事情就是刪除XML檔案

然後編寫一個類用於代替XML檔案實現配置功能:

使用@Configuration將這個類註冊為Spring容器

使用@ComponentScan表示我們自己的包目錄掃描

掃描的類會被這個配置註冊成Bean,一般那些類會被標記有葉子

使用@PropertySource指定配置檔案路徑

檔案內的資訊可以被表示式獲取到

使用@Bean註冊

用於jar包的資源獲取,XML我們使用的是bean標籤

當然還需要以一個方法的形式返回:

方法的名字就是Bean的ID屬性,方法的返回型別即Class屬性

如果我們不想使用方法的名字,可以對Bean再賦值名字的值:

使用@Scope註解改變Bean的範圍

當然,如果我們希望這個Bean不是單例的,在XML中則設定scope屬性

使用@Import合併配置類

Spring允許我們設定多個配置類,這和設定多個XML配置檔案是一樣的

在XML檔案中我們使用import標籤將其他XML檔案統一匯入到一個檔案中,這也是一個道理

例如這裡配置了一個Jdbc配置類:

我們就可以把他匯入到我們上面的配置類去:

然後我們載入容器例項的時候就不需要分開匯入了

注意我們是使用這個註解載入的容器例項:

@Autowired再談自動裝配:

首先自動裝配是針對引用資料型別的,例如我們的dao,service,包括一些其他的資料來源等物件

基本資料型別,或者說簡單的常用資料型別無法使用@Autowired(這種玩意你讓Spring裝配幹嘛,直接賦值不就行了)

還有個要求是被裝配的物件所屬的類必須也被Spring容器註冊了

缺陷:自動裝配要求容器中只能有一個符合要求的型別,才可以裝配上

如果你註冊了多個同類型的bean,該註解無法裝配,因為spring不知道你到底需要裝配哪一個bean

@Autowired在全註解中的應用:

在bean方法的引數中如果需要注入引用型別,是預設使用自動裝配完成的

例如這個例子:

資料來源是預設打上了自動裝配註解的

使用@Qulifier指定要注入的同類型bean

回到上面的多個同類型的問題,如果我們配置了多個數據源,那麼可以在這裡新增此註解即可

其意義是指定bean的id屬性為註解所指定的相匹配的同類型bean來注入

使用@Value賦值

一般用於對一些類的普通屬性進行賦值

這裡我為了建立資料來源圖省事就直接對引數打上註解進行賦值

2、【SpringTest 使用】

為什麼需要Spring-Test?

因為Spring容器固定的需要這樣手寫的方式加載出來:

        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringApplicationConfiguration.class);
        QueryRunner queryRunner = applicationContext.getBean("queryRunner", QueryRunner.class);

所以測試的姿勢應該更簡單些

需要對應的依賴:

特別注意Junit版本不得低於4.12,不然Spring都載入不到

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.2.7.RELEASE</version>
</dependency>

然後是測試類的編寫:

@Runwith註解測試類使用何種資源執行

@ContextConfiguration用於載入容器配置,一個XML,一個配置類這兩種

一個是不要忘記載入容器,第二個是不要載入錯誤的配置資源

自己寫什麼配置方式,就載入什麼配置資源

程式碼:

import cn.echo42.config.SpringApplicationConfiguration;
import cn.echo42.pojo.User;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * @author DaiZhiZhou
 * @file Spring
 * @create 2020-07-27 16:08
 */

@RunWith(SpringJUnit4ClassRunner.class) // 指定執行類
// @ContextConfiguration(locations = "classpath:xxx-context.xml") xml檔案載入
@ContextConfiguration(classes = SpringApplicationConfiguration.class) // 配置類載入 指定載入容器
public class SpringTest {

    @Autowired
    private QueryRunner queryRunner;

    @Test
    public void jdbcTest() throws Exception{
        for (User user : queryRunner.query("SELECT * FROM `sys_user`", new BeanListHandler<User>(User.class))) {
            System.out.println(user);
        }
    }
}

import cn.echo42.config.SpringApplicationConfiguration;
import cn.echo42.pojo.User;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.util.List;

/**
 * @author DaiZhiZhou
 * @file Spring
 * @create 2020-07-27 13:43
 */


public class AnnotationTest {

    @Test
    public void annotationGet() throws Exception {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringApplicationConfiguration.class);
        QueryRunner queryRunner = applicationContext.getBean("queryRunner", QueryRunner.class);
        System.out.println(queryRunner);
        List<User> userList = queryRunner.query("SELECT * FROM `sys_user`", new BeanListHandler<User>(User.class));
        for (User user : userList) {
            System.out.println(user);
        }
    }
}

package cn.echo42.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;

import javax.sql.DataSource;

/**
 * @author DaiZhiZhou
 * @file Spring
 * @create 2020-07-27 14:37
 */

@Configuration // 表示註解該類為一個配置類
@ComponentScan("cn.echo42") // 指定spring在建立容器時要掃描的包,一般直接掃描總目錄
@PropertySource("classpath:jdbc.properties") //指定properties檔案的位置
public class SpringApplicationConfiguration {

    // 在這裡引用外部Jar包的資源

    @Bean("queryRunner")
    @Scope("prototype")
    public QueryRunner getQueryRunner(@Qualifier("dataSource") DataSource dataSource){
        return new QueryRunner(dataSource);
    }

    @Bean("dataSource") //
    public DataSource getDataSource(
            @Value("${jdbc.driverClassName}") String driver,
            @Value("${jdbc.url}")String url,
            @Value("${jdbc.user}")String username,
            @Value("${jdbc.password}")String password ) {
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(driver);
        druidDataSource.setUrl(url);
        druidDataSource.setUsername(username);
        druidDataSource.setPassword(password);
        return druidDataSource;
    }
}

jdbc.driverClassName = com.mysql.cj.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/oa?serverTimezone=GMT
jdbc.user = root
jdbc.password = 123456