一、利用 spring的 IoC(xml配置)來實作賬戶的 CRUD[掌握]
步驟一:建立工程并導入依賴(pom.xml:)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.itcast.spring</groupId>
<artifactId>spring_day02</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--springIOC相關-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<!--springjdbc相關-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<!-- 連接配接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
步驟二:建立資料庫和實體類
建立資料庫:
create table account(
id int primary key auto_increment,
name varchar(40),
money float
)character set utf8 collate utf8_general_ci;
insert into account(name,money) values('aaa',1000);
insert into account(name,money) values('bbb',1000);
insert into account(name,money) values('ccc',1000);
自己編寫實體類Account(私有,有getter和setter方法、重寫tostring)
步驟三:建立service接口和實作類
接口:

實作類:
步驟四:建立dao接口和實作類
接口:
實作類:
步驟五:建立配置檔案
步驟六:建立測試用例
步驟七:加載外部資源檔案
在類的根路徑下添加jdbc.properties:
内容如下:
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/heima25
jdbc.username=root
jdbc.password=root
修改applicationContext.xml:
二、 基于注解的IOC配置[掌握]
1、 明确:寫在最前
注解配置和xml配置要實作的功能都是一樣的,都是要降低程式間的耦合。
2、環境搭建
2.1 建立maven工程并導入坐标
複制spring_day02然後重命名為spring_day02_02即可:重命名工程、重命名pom.xml中的artifactId,删除其他檔案隻留下src和pom.xml,然後在idea中打開即可。
2.2 使用注解裝配bean
@Component
作用: 在類上使用該注解,把資源讓spring來管理。相當于在xml中配置一個bean。( <bean id="" class="">)
屬性: value:指定bean的id。如果不指定value屬性,預設bean的id是目前類的類名。首字母小寫。
@Controller @Service @Repository
他們三個注解都是針對@Component的衍生注解,他們的作用及屬性都是一模一樣的。
他們隻不過是提供了更加明确的語義化。
@Controller:一般用于表現層(web)的注解。
@Service:一般用于業務層(service)的注解。
@Repository:一般用于持久層(dao)的注解。
細節:如果注解中有且隻有一個屬性要指派時,且名稱是value,value在指派時可以不寫。
步驟一:建立配置檔案
先配置注解掃描的包,如圖:紅色
步驟二:使用注解裝配bean
裝配service:
裝配dao:
步驟三:進行測試
建立demo的測試方法分别擷取service的實作類和dao的實作類,發現@Component的注解已經生效。
但是如果使用其他的crud的測試方法,會報空指針異常。
原因:AccountDaoImpl并沒有被注入到AccountServiceImpl中。(相當于xml檔案中紅色部分沒有配置)
<bean id="accountService" class="cn.itcast.service.impl.AccountServiceImpl"> //@Component
<property name="accountDao" ref="accountDao"></property> //@Autowired
</bean>
2.3 用于注入資料的
@Autowired
作用:
自動按照類型注入。當使用注解注入屬性時,set方法可以省略。它隻能注入其他bean類型。當有多個類型比對時,使用要注入的對象的變量名稱作為bean的id,在spring容器查找,找到了也可以注入成功。找不到就報錯。
service實作類
dao實作類:
@Qualifier
作用: (1)在自動按照類型注入的基礎之上,再按照Bean的id注入。它在給字段注入時不能獨立使用,必須和@Autowire一起使用;(2)但是給方法參數注入時,可以獨立使用。
屬性: value:指定bean的id。
添加第二個dao實作類:
内容如下:複制AccountDaoImpl後重命名為AccountDaoImpl2即可
指定注入AccountDaoImpl2:
@Resource
作用: 直接按照Bean的id注入。它也隻能注入其他bean類型。(相當于@Autowired+@Qualifier)
屬性: name:指定bean的id。
@Value
作用: 注入基本資料類型和String類型資料的
屬性: value:用于指定值
注解裝配bean和注解注入的使用方式(重點)
1、自己編寫的類,都可以使用注解裝配到容器中。
2、沒有辦法使用注解裝配的第三方的類,可以使用<bean>标簽裝配。
3、隻要是在spring容器中的bean,都可以使用注解注入。
2.4 用于改變作用範圍的
相當于:<bean id="" class="" scope="">
@Scope
作用:指定bean的作用範圍。
屬性:value:指定範圍的值。取值:singleton prototype request session globalsession
2.5 和生命周期相關的:(了解)
相當于:<bean id="" class="" init-method="" destroy-method="" />
@PostConstruct
作用:用于指定初始化方法。
@PreDestroy作用:
作用:用于指定銷毀方法。
2.6 關于Spring注解和XML的選擇問題
注解的優勢:
配置簡單,維護友善(我們找到類,就相當于找到了對應的配置)。
XML的優勢:
修改時,不用改源碼。
Spring管理Bean方式的比較:
三、案例:使用注解IOC改造作業[掌握]
步驟一:建立maven工程并導入坐标
複制spring_day02_02然後重命名為spring_day02_03即可:重命名工程、重命名pom.xml中的artifactId,删除其他檔案,隻留下src和pom.xml後,通過idea打開即可。
步驟二:建立web層
建立一個AccountController,假設屬于web層,隻需測試新增方法即可。
步驟三:建立service接口和實作類
實作類:修改注入方式即可。
接口:和之前的一樣
實作類:
步驟四:建立dao接口和實作類
實作類:修改注入方式即可。
接口:和之前的一樣
實作類:
步驟六:建立配置檔案
步驟七:建立測試用例
建立web層的測試用例:
2、待改造的問題
我們發現,之是以我們現在離不開xml配置檔案,是因為我們有一句很關鍵的配置:
<!-- 告知spring架構在,讀取配置檔案,建立容器時,掃描注解,依據注解建立對象,并存入容器中 -->
<context:component-scan base-package="cn.itcast"></context:component-scan>
如果他要也能用注解配置,那麼我們就離脫離xml檔案又進了一步。
另外,資料源和QueryRunner的配置也需要靠注解來實作。
3、新注解說明
@Configuration
作用:
用于指定目前類是一個spring配置類,當建立容器時會從該類上加載注解。(相當于applicationContext.xml檔案)
擷取容器時需要使用AnnotationApplicationContext(有@Configuration注解的類.class)。
示例代碼:
@Configuration
public class SpringConfiguration {
}
注意:
我們已經把配置檔案用類來代替了,但是如何配置建立容器時要掃描的包呢?
請看下一個注解
@ComponentScan
作用:
用于指定spring在初始化容器時要掃描的包。作用和在spring的xml配置檔案中的:
<context:component-scan base-package="cn.itcast"></context:component-scan>
屬性:
Value(單獨使用可省略):用于指定要掃描的包。和标簽中的base-Package屬性作用一樣。
示例代碼:
@Configuration //spring的配置類,相當于applicationContext.xml檔案
@ComponentScan("cn.itcast") //配置掃描的包
public class SpringConfiguration {
}
注意:
我們已經配置好了要掃描的包,但是資料源和QueryRuner對象如何從配置檔案中移除呢?
請看下一個注解。
@Bean
作用: 該注解隻能寫在方法上,将方法的傳回值作為一個bean,并且放入spring容器。
屬性: name:給目前@Bean注解方法建立的對象指定一個名稱(即bean的id)。
注意:
我們已經把資料源和QueryRunner從配置檔案中移除了,此時可以删除bean.xml了。
但是由于沒有了配置檔案,建立資料源的配置又都寫死在類中了。如何把它們配置出來呢?
請看下一個注解。
@PropertySource
作用:
用于加載.properties檔案中的配置(加載外部資源檔案)。例如我們配置資料源時,可以把連接配接資料庫的資訊寫到properties配置檔案中,就可以使用此注解指定properties配置檔案的位置。
屬性:
value[]:用于指定properties檔案位置。如果是在類路徑下,需要寫上classpath:
@Import
作用:
用于導入其他配置類,在引入其他配置類時,其他類上可以不用再寫@Configuration注解。當然,寫上也沒問題。
屬性:
value[]:用于指定其他配置類的位元組碼。
示例代碼:
@Configuration //聲明這是一個配置類
@ComponentScan("cn.itcast") //配置掃描包
@Import(value = { JdbcConfig.class }) //導入JdbcConfig配置類(首字母大寫)
public class SpringConfiguration {
}
@Configuration//寫不寫都行
@PropertySource(value = { "classpath:jdbc.properties" }) //加載外部資源
public class JdbcConfig {
}
注意:
我們已經把要配置的都配置好了,但是新的問題産生了,由于沒有配置檔案了,如何擷取容器呢?
請看下一小節。
通過注解擷取容器
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
4、純注解案例
步驟一:環境搭建
複制之前的工程,重命名工程名稱,重命名pom.xml中的artifactId, 删除其他檔案,隻留下src和pom.xml後,通過idea打開即可。
步驟二:建立配置類
如果在一個配置類中需要裝配很多的bean到容器中,那麼顯然将所有的bean放在一個配置類是非常不利于管理的,是以我們可以選擇将bean分拆到其他類中單獨管理,最後再通過配置類來引入其他類即可。
在resources類的根目錄下建立properties資源檔案:
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/heima25
jdbc.username=root
jdbc.password=root
springConfiguration:
步驟三:測試
四、 Spring整合junit
1、 測試類中的問題和解決思路
問題:
在測試類中,每個測試方法都有以下兩行代碼:
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
AccountController accountController = (AccountController) ac.getBean("accountController");
這兩行代碼的作用是擷取容器,如果不寫的話,直接會提示空指針異常。是以又不能輕易删掉。
解決思路分析
針對上述問題,我們需要的是程式能自動幫我們建立容器。一旦程式能自動為我們建立spring容器,我們就無須手動建立了,問題也就解決了。
我們都使用過junit,但是junit都無法知曉我們是否使用了spring架構,更不用說幫我們建立spring容器了。不過好在,junit給我們暴露了一個注解,可以讓我們替換掉它的運作器。
這時,我們需要依靠spring架構,因為它提供了一個運作器,可以讀取配置檔案(或注解)來建立容器。我們隻需要告訴它配置檔案在哪就行了。
2、 涉及的注解
@RunWith
作用: 替換掉junit的運作器,換成一個可以初始化spring容器的運作器。
屬性: value:單獨配置時,value屬性名稱可以省略,配置SpringJUnit4ClassRunner.class來代替原來junit的運作器
@ContextConfiguration
作用: 加載配置類或者xml配置檔案
屬性:
value[]:用來指定xml配置檔案的路徑 location
class[]: 用來指定配置類 classes
3、 Xml的配置步驟
步驟一:環境搭建
複制之前的spring_day02_03(含xml配置檔案)工程重命名後修改pom.xml中的artifactId,然後删除其他檔案,隻留下src和pom.xml後,通過idea打開即可。
步驟二:導入spring-test的坐标
此處需要注意的是,spring5及以上版本要求junit的版本必須是4.12及以上,否則用不了。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
步驟三:測試
4、 純注解的配置步驟(配置類)
步驟一:環境搭建
複制spring_day02_04(含配置類)重命名後修改pom.xml中的artifactId,然後删除其他檔案,隻留下src和pom.xml後,通過idea打開即可。
步驟二:導入spring-test的坐标
此處需要注意的是,spring5及以上版本要求junit的版本必須是4.12及以上,否則用不了。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
步驟三:測試
-
注解總結
-
用于裝配Bean的注解
-
@Component(value=”xxx”):
一般用于将三層以為的bean裝配到容器中,value可以省略,value的屬性值作為bean的id
@Component的三個衍生注解:
@Controller(value=”xxx”):
一般用于将web層裝配到容器中,使用方法和@Component(value=”xxx”)一摸一樣
@Service(value=”xxx”):
一般用于将web層裝配到容器中,使用方法和@Component(value=”xxx”)一摸一樣
@Repository(value=”xxx”):
一般用于将web層裝配到容器中,使用方法和@Component(value=”xxx”)一摸一樣
-
用于屬性注入的注解
@Autowired:
隻能按照bean類型注入,如果有多個類型比對,預設将屬性名稱作為id去容器中查找。
@Qualifier:
一般和@Autowired配合使用,用來注入指定id的bean,做方法的參數中可以獨立使用
@Resource:
用來注入指定id的bean類型,相當于@Autowired+@Qualifier
@Value:
隻能注入基本類型等資料,不能注入bean類型,可以使用${}在資源檔案中擷取資料,前提是,外部資源檔案被加載。
-
作用域的
@Scope:
用于指定bean的作用域,一般就是singleton和prototype
-
生命周期相關的
@PostConstruct:
用于指定某一個方法為初始化方法
@PreDestroy:
用于指定某一個方法為銷毀方法
-
其他配置類相關的
@Configuration:
聲明一個類為配置類,用于替代applicationContext.xml的
@ComponentScan:
用于開啟注解掃描的包
@Import:
用于導入其他類的
@PropertySource:
用于加載外部資源檔案的
@Bean:
用于将方法傳回的bean類型的對象裝配到容器中
-
Junit相關的
@RunWith:
用于替換底層的運作器,初始化spring容器的
@ContextConfiguration
用于指定配置檔案或者配置類的