1. 程式人生 > >Spring(基於註解的IOC配置)

Spring(基於註解的IOC配置)

一、利用 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.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)的註解。

細節:如果註解中有且只有一個屬性要賦值時,且名稱是valuevalue在賦值時可以不寫。

步驟一:建立配置檔案

先配置註解掃描的包,如圖:紅色

步驟二:使用註解裝配bean

裝配service:

/**

 * @Component註解:相當於配置了<bean>標籤

 *     value = "accountService":相當於配置了bean標籤的id屬性,單獨配置value時,可以省略value屬性名稱。

 */

裝配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型別。當有多個型別匹配時,使用要注入的物件的變數名稱作為beanid,在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)

示例程式碼:

/**

 * spring的配置類,相當於applicationContext.xml檔案

 */

@Configuration

public class SpringConfiguration {

}

注意:

        我們已經把配置檔案用類來代替了,但是如何配置建立容器時要掃描的包呢?

請看下一個註解

@ComponentScan

作用:

        用於指定spring在初始化容器時要掃描的包。作用和在springxml配置檔案中的:

         <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>

步驟三:測試

  1. 註解總結

    1. 用於裝配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”)一摸一樣

  1. 用於屬性注入的註解

@Autowired:

       只能按照bean型別注入,如果有多個型別匹配,預設將屬性名稱作為id去容器中查詢。

@Qualifier:

       一般和@Autowired配合使用,用來注入指定id的bean,做方法的引數中可以獨立使用

@Resource:

       用來注入指定id的bean型別,相當於@Autowired+@Qualifier

@Value:

       只能注入基本型別等資料,不能注入bean型別,可以使用${}在資原始檔中獲取資料,前提是,外部資原始檔被載入

  1. 作用域的

@Scope:

       用於指定bean的作用域,一般就是singleton和prototype

  1. 生命週期相關的

@PostConstruct:

       用於指定某一個方法為初始化方法

@PreDestroy:

       用於指定某一個方法為銷燬方法

  1. 其他配置類相關的

@Configuration

       宣告一個類為配置類,用於替代applicationContext.xml的

@ComponentScan:

       用於開啟註解掃描的包

@Import:

       用於匯入其他類的

@PropertySource:

       用於載入外部資原始檔的

@Bean:

       用於將方法返回的bean型別的物件裝配到容器中

  1. Junit相關的

@RunWith:

       用於替換底層的執行器,初始化spring容器的

@ContextConfiguration

       用於指定配置檔案或者配置類的