【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