Spring入門——IOC

Spring概述

         Spring是分層的、JavaSE/EE一站式(full-stack)、輕量級開源框架。以IoCInverse Of Control:反轉控制)和AOPAspect Oriented Programming:面向切面編程)爲內核,提供了表現層Spring MVC和持久層Spring JDBC以及業務層事務管理等衆多的企業級應用技術,還能整合開源世界衆多著名的第三方框架和類庫,逐漸成爲使用最多的Java EE企業應用開源框架。

 

spring 的優勢

方便解耦,簡化開發、 AOP編程的支持、 聲明式事務的支持、 方便程序的測試、 方便集成各種優秀框架、 降低JavaEE API的使用難度

關於框架的特性,我們也會俗稱Spring爲開發架構的粘合劑。

 

spring 的體系結構

 

Spring的核心

IoC(Inverse of Control 控制反轉): 將對象創建權利交給Spring工廠進行管理。

AOP(Aspect Oriented Programming 面向切面編程),基於動態代理的功能增強方式。

 

1、IoC 的概念和作用

什麼是程序的耦合: 我們在開發中,會寫很多的類,而有些類之間不可避免的產生依賴關係,這種依賴關係稱之爲耦合。

代碼中的體現:早期我們的 JDBC 操作,註冊驅動時,我們爲什麼不使用 DriverManager 的 register 方法,而是採 用 Class.forName 的方式?原因就是:我們的類依賴了數據庫的具體驅動類(MySQL),如果這時候更換了數據庫品牌(比如 Oracle), 需要修改源碼來重新數據庫驅動。

解決程序耦合的思路:當是我們講解 jdbc 時,是通過反射來註冊驅動的,代碼如下:

Class.forName("com.mysql.jdbc.Driver");//此處只是一個字符串

此時的好處是,我們的類中不再依賴具體的驅動類,此時就算刪除 mysql 的驅動 jar 包,依然可以編譯(運行就不要想了,沒有驅動不可能運行成功的)。

 

工廠模式解耦:

代碼準備:

dao接口和實現類:

dao接口:

public interface IAccountDao {
    /**
     * 模擬保存賬戶
     */
    void saveAccount();
}

dao實現類:

public class AccountDaoImpl implements IAccountDao {



    public void saveAccount() {

       System.out.println("保存了賬戶");

    }

}

 

service接口和實現類:

service接口:

public interface IAccountService {



    /**

     * 模擬保存賬戶

     */

    void saveAccount();

}

service實現類:

public class AccountServiceImpl implements IAccountService {



    //手動初始化

    private IAccountDao accountDao = new AccountDaoImpl();



    public void saveAccount() {

       accountDao.saveAccount();

    }

}

 

Web層:模擬一個表現層

public class Client {



    public static void main(String[] args) {

      

       IAccountService as = new AccountServiceImpl();            

       as.saveAccount();

    }

}

代碼解耦

在上述的代碼中,代碼耦合體現在兩個地方: service中手動初始化了dao; web層手動初始化了service

        而解耦最明顯的特徵就是:哪怕缺少一個對象,起碼在編譯時不會報錯,只有在運行時纔會報錯。既然在jdbc中我們可以使用反射來進行解耦,那麼我們能否在三層中使用這個方案呢?

第一步:創建工廠

在resources目錄下創建資源文件,beans.properties:

accountDao=cn.itcast.dao.impl.AccountDaoImpl

accountService=cn.itcast.service.impl.AccountServiceImpl

第二步:編寫一個工廠:用來反射生成需要的對象

public class BeanFactory {

    private static ResourceBundle rb = ResourceBundle.getBundle("beans");



    private static Map<String,Object> map = new HashMap<String,Object>();



    static{

        try {

            //獲取所有的key

            Enumeration<String> keys = rb.getKeys();

            //遍歷所有的key

            while (keys.hasMoreElements()){

                String key = keys.nextElement();

                //通過key獲取value

                String value = rb.getString(key);

                //初始化對象

                Object bean = Class.forName(value).newInstance();

                //將所有初始化的對象存入map中。

                map.put(key,bean);

            }



        } catch (Exception e) {

            e.printStackTrace();

        }



    }



    /**

     * 對外提供一個從map中獲取對象的方法

     * @param beanName

     * @return

     */

    public static Object getBean(String beanName){

        return map.get(beanName);

    }

}

第三步:代碼解耦

Web層:

public class Client {

    public static void main(String[] args) {

        //手動初始化

        //IAccountService accountService = new AccountServiceImpl();

        //從容器中獲取

        IAccountService accountService = (IAccountService) BeanFactory.getBean("accountService");

        accountService.saveAccount();

    }

}

Service層:

public class AccountServiceImpl implements IAccountService {



    //手動初始化

    //private IAccountDao accountDao = new AccountDaoImpl();

    //從容器中獲取

    private IAccountDao accountDao = (IAccountDao) BeanFactory.getBean("accountDao");

    public void saveAccount() {

        accountDao.saveAccount();

    }

}

控制反轉-Inversion Of Control

我們通過使用工廠模式,實現了表現層——業務層以及業務層——持久層的解耦。

它的核心思想就是:(1) 通過讀取配置文件反射創建對象;(2) 把創建出來的對象都存起來,當我們下次使用時可以直接從存儲的位置獲取。

 

2、使用 spring IOC解決程序耦合

案例的前期準備[會用]:

一、創建工程

二、業務層接口和實現類

接口:

public interface IAccountService {



    /**

     * 模擬保存賬戶

     */

    void saveAccount();

}

實現類:

public class AccountServiceImpl implements IAccountService {

    //手動初始化

    private IAccountDao accountDao = new AccountDaoImpl();

    @Override

    public void saveAccount() {

        accountDao.saveAccount();

    }

}

三、持久層接口和實現類

接口:

public interface IAccountDao {

    void saveAccount();

}

實現類:

public class AccountDaoImpl implements IAccountDao {

    @Override

    public void saveAccount() {

        System.out.println("保存賬戶");

    }

}

四、表現層

public class Client {

public static void main(String[] args) {

IAccountService accountService = new AccountServiceImpl();

accountService.saveAccount();

}

}

 

Spring基於xmlIOC解耦方案

一、 創建配置文件模板

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

</beans>

Idea裏配置模板

二、創建配置文件

IoC底層實現:工廠(設計模式)+反射(機制) + 配置文件

在spring中,工廠和反射機制由框架完成,我們只需要編寫配置文件即可。

在resources下創建:applicationContext.xml

如果創建的配置文件報紅,刷新maven即可

三、導入依賴 

<dependencies>

        <!--IOC相關依賴-->

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-context</artifactId>

            <version>5.0.6.RELEASE</version>

        </dependency>

    </dependencies>

四、將dao和service的實現類裝配到容器中

<!-- spring 將自己管理的資源統稱爲bean

            id:資源標識名稱,相當於properties中的key,通過該名稱可以獲取對象

            class:資源路徑,一般是實現類的全路徑

         -->



    <!-- 將service實現類裝配到容器中 -->

    <bean id="accountService" class="cn.itcast.service.impl.AccountServiceImpl"></bean>



    <!-- 將dao實現類裝配到容器中 -->

    <bean id="accountDao" class="cn.itcast.dao.impl.AccountDaoImpl"></bean>

五、從容器中獲取dao和service實現類

將web層代碼修改如下:

public class Client {

public static void main(String[] args) {

//加載配置文件,獲取spring工廠,從容器中獲取dao和service的實現類

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

//從容器中獲取service

IAccountService accountService = (IAccountService) ac.getBean("accountService");

System.out.println(accountService);

//從容器中獲取dao

IAccountDao accountDao = (IAccountDao) ac.getBean("accountDao");

System.out.println(accountDao);
}
}

 

Spring基於 XML IOC 細節[掌握]

spring 中工廠的類結構圖

 

BeanFactory ApplicationContext 的區別

BeanFactory 纔是 Spring 容器中的頂層接口。

ApplicationContext 是它的子接口。

BeanFactory 和 ApplicationContext 的區別:  創建對象的時間點不一樣。  

ApplicationContext:只要一讀取配置文件,默認情況下就會創建對象。  

BeanFactory:什麼使用什麼時候創建對象。

 

Beanfactory的用法:

     BeanFactory ac = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));

 

IOC bean 籤和管理對象細節

bean 標籤

作用: 

用於配置對象讓 spring 來創建的。 

默認情況下它調用的是類中的無參構造函數。如果沒有無參構造函數則不能創建成功。

屬性:

  • id:給對象在容器中提供一個唯一標識。用於獲取對象。 

  • class:指定類的全限定類名。用於反射創建對象。默認情況下調用無參構造函數。 

  • scope:指定對象的作用範圍。   

                * singleton :默認值,單例的.   

                * prototype :多例的.

  • init-method:指定類中的初始化方法名稱(生命週期相關)。 

  • destroy-method:指定類中銷燬方法名稱(生命週期相關)。

 

bean 的生命週期

單例對象:scope="singleton"

                   一個應用只有一個對象的實例。它的作用範圍就是整個應用。

                   生命週期:

                            對象出生:當應用加載,創建容器時,對象就被創建了。

                            對象活着:只要容器在,對象一直活着。

                            對象死亡:當應用卸載,銷燬容器時,對象就被銷燬了。

多例對象:scope="prototype"

                   每次訪問對象時,都會重新創建對象實例。

                   生命週期:

                            對象出生:當使用對象時,創建新的對象實例(getBean)。

                            對象活着:只要對象在使用中,就一直活着。

                            對象死亡:當對象長時間不用時,被java的垃圾回收器回收了。

生命週期方法:

        init-method:指定類中的初始化方法名稱(生命週期相關)。 

        destroy-method:指定類中銷燬方法名稱(生命週期相關)。

 

實例化 Bean 的三種方式

第一種方式:使用默認無參構造函數創建對象

       在默認情況下:   它會根據默認無參構造函數來創建類對象。如果 bean 中沒有默認無參構造函數,將會創建失敗

 

第二種方式:使用靜態工廠的方法創建對象 

    使用工廠中的靜態方法創建對象,並存入 spring 容器 

    id 屬性:指定 bean 的 id,用於從容器中獲取  

    class 屬性:指定靜態工廠的全限定類名  

    factory-method 屬性:指定生產對象的靜態方法

 

第三種方式:使用實例工廠的方法創建對象

    先把工廠的創建交給 spring 來管理。  

    然後再使用工廠的 bean 來調用裏面的方法  

    factory-bean 屬性:用於指定實例工廠 bean 的 id。  

    factory-method 屬性:用於指定實例工廠中創建對象的方法。

 

默認無參構造創建對象

<!-- 將service實現類裝配到容器中 -->

<bean id="accountService" class="cn.itcast.service.impl.AccountServiceImpl"></bean>

 

靜態工廠方法創建對象

第一步:創建靜態工廠

/**

 * 假設service的實現類是由工廠中的靜態方法創建的

 */

public class StaticFactory {

public static IAccountService createAccountService(){

return new AccountServiceImpl();

}

}

第二步:編寫配置文件

<!-- 通過靜態工廠方法創建對象並裝配到容器中 -->

<bean id="accountService" class="cn.itcast.utils.StaticFactory" factory-method="createAccountService"></bean>

第三步:測試

public class ClientStatic {

public static void main(String[] args) {

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

IAccountService accountService = (IAccountService) ac.getBean("accountService");

System.out.println(accountService);

}

}

 

實例工廠方法創建對象

第一步:創建實例工廠

/**

 * 假設service的實現類是由一個工廠的非靜態方法創建的

 */

public class InstanceFactory {

public IAccountService createAccountService(){

return new AccountServiceImpl();

}

}

第二步:編寫配置文件

<!-- 將實例工廠裝配到容器中 -->

<bean id="instanceFactory" class="cn.itcast.utils.InstanceFactory"></bean>



<!-- 調用實例工廠中的非靜態方法創建對象 -->

<bean id="accountService" factory-bean="instanceFactory" factory-method="createAccountService"></bean>

第三步:測試

public class ClientInstance {

public static void main(String[] args) {

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

IAccountService accountService = (IAccountService) ac.getBean("accountService");

System.out.println(accountService);

}

}

 

Spring的依賴注入

依賴注入的概念

依賴注入:Dependency Injection。它是 spring 框架核心 ioc 的具體實現。

我們的程序在編寫時,通過控制反轉,把對象的創建交給了 spring,但是代碼中不可能出現沒有依賴的情況。 ioc 解耦只是降低他們的依賴關係,但不會消除。例如:我們的業務層仍會調用持久層的方法。

那這種業務層和持久層的依賴關係,在使用 spring 之後,就讓 spring 來維護了。

簡單的說,就是坐等框架把持久層對象傳入業務層,而不用我們自己去獲取。

 

一、 構造方法注入屬性

顧名思義,就是使用類中的構造函數,給成員變量賦值。注意,賦值的操作不是我們硬編碼的,而是通過配置的方式,讓spring框架來爲我們注入。

要求:

  1. bean對象需要創建有參數的構造方法

  2. 在配置文件中通過constructor-arg標籤注入屬性

創建AccountServiceImpl2: 創建並添加有參構造函數

public class AccountServiceImpl2 implements IAccountService {

private String name;

private Integer age;

private IAccountDao accountDao;



//使用有參構造來注入屬性

public AccountServiceImpl2(String name, Integer age, IAccountDao accountDao) {

this.name = name;

this.age = age;

this.accountDao = accountDao;

}



public void saveAccount() {

System.out.println(name+"..."+age+"..."+accountDao);

}

}

編寫配置文件

<!--

使用構造函數注入屬性值:

涉及的標籤: constructor-arg

屬性:

index:指定參數在構造函數參數列表的索引位置

name:指定參數在構造函數中的名稱,指定給誰賦值



=======上面三個屬性都是指給誰賦值,下面兩個屬性指的是賦什麼值的==============



value:它能賦的值是基本數據類型和 String 類型

ref:它能賦的值是其他 bean 類型,也就是說,必須得是在配置文件中配置過的 bean



-->

<bean id="accountService2" class="cn.itcast.service.impl.AccountServiceImpl2">

<constructor-arg name="name" value="張三"></constructor-arg>

<constructor-arg name="age" value="18"></constructor-arg>

<constructor-arg name="accountDao" ref="accountDao"></constructor-arg>

</bean>

 

二、Set方法注入

顧名思義,就是使用類中的set方法,給成員變量賦值。注意,賦值的操作不是我們硬編碼的,而是通過配置的方式,讓spring框架來爲我們注入。

要求:

  1. 在配置文件中通過proprety標籤注入屬性

創建AccountServiceImpl3:創建並提供屬性的set方法

public class AccountServiceImpl3 implements IAccountService {

private String name;

private Integer age;

private IAccountDao accountDao;



public void setName(String name) {

this.name = name;

}



public void setAge(Integer age) {

this.age = age;

}



public void setAccountDao(IAccountDao accountDao) {

this.accountDao = accountDao;

}



public void saveAccount() {

System.out.println(name+"..."+age+"..."+accountDao);

}
}

編寫配置文件

<!--

通過配置文件給 bean 中的屬性傳值:使用 set 方法的方式

涉及的標籤:

Property相關屬性:

name:找的是類中 set 方法後面的部分

ref:給屬性賦值是其他 bean 類型的

value:給屬性賦值是基本數據類型和 string 類型的

實際開發中,此種方式用的較多。

-->

<bean id="accountService3" class="cn.itcast.service.impl.AccountServiceImpl3">

<property name="name" value="李四"></property>

<property name="age" value="20"></property>

<property name="accountDao" ref="accountDao"></property>

</bean>

創建Client3測試

public class Client3 {

public static void main(String[] args) {

//加載配置文件,獲取spring工廠,從容器中獲取dao和service的實現類

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

//從容器中獲取service

IAccountService accountService = (IAccountService) ac.getBean("accountService3");

accountService.saveAccount();

}

}

 

三、P名稱空間注入

此種方式是通過在 xml中導入 p名稱空間,使用 p:propertyName屬性 來注入數據,它的本質仍然是調用類中的 set 方法實現注入功能

創建AccountServiceImpl4

public class AccountServiceImpl4 implements IAccountService {

private String name;

private Integer age;

private IAccountDao accountDao;



public void setName(String name) {

this.name = name;

}



public void setAge(Integer age) {

this.age = age;

}



public void setAccountDao(IAccountDao accountDao) {

this.accountDao = accountDao;

}



public void saveAccount() {

System.out.println(name+"..."+age+"..."+accountDao);

}

}

編寫配置文件

xmlns:p="http://www.springframework.org/schema/p"

配置文件:

<?xml version="1.0" encoding="UTF-8"?>



<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:p="http://www.springframework.org/schema/p"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd">



<!-- 將dao實現類裝配到容器中 -->

<bean id="accountDao" class="cn.itcast.dao.impl.AccountDaoImpl"></bean>



<bean id="accountService4" class="cn.itcast.service.impl.AccountServiceImpl4" p:name="zhangsan" p:age="18" p:accountDao-ref="accountDao"></bean>

</beans>

創建Client4測試

public class Client4 {

    public static void main(String[] args) {

        //加載配置文件,獲取spring工廠,從容器中獲取dao和service的實現類

        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

        //從容器中獲取service

        IAccountService accountService = (IAccountService) ac.getBean("accountService4");

        accountService.saveAccount();

    }

}

四、複雜類型的注入

顧名思義,就是給類中的集合成員傳值,它用的也是set方法注入的方式,只不過變量的數據類型都是集合。 我們這裏介紹注入數組,List,Set,Map,Properties

創建AccountServiceImpl5

public class AccountServiceImpl5 implements IAccountService {

private String[] myStrs;

private List<String> myList;

private Set<String> mySet;

private Map<String, String> myMap;

private Properties myProps;





public void setMyStrs(String[] myStrs) {

this.myStrs = myStrs;

}





public void setMyList(List<String> myList) {

this.myList = myList;

}





public void setMySet(Set<String> mySet) {

this.mySet = mySet;

}





public void setMyMap(Map<String, String> myMap) {

this.myMap = myMap;

}





public void setMyProps(Properties myProps) {

this.myProps = myProps;

}





public void saveAccount() {

System.out.println(myStrs);

System.out.println(myList);

System.out.println(mySet);

System.out.println(myMap);

System.out.println(myProps);

}

}

編寫配置文件

<!--

注入集合屬性:

使用set方法注入集合屬性:

   array:一般用來設置數組

   list:一般用來設置list集合

   map:一般用來設置map集合

   props:一般用來設置properties

-->

  <bean id="accountService5" class="cn.itcast.service.impl.AccountServiceImpl5">

      <property name="myStrs">

          <array>

              <value>AAA</value>

              <value>BBB</value>

              <value>CCC</value>

          </array>

      </property>

      <property name="myList">

          <list>

              <value>AAA</value>

              <value>BBB</value>

              <value>CCC</value>

          </list>

      </property>

      <property name="mySet">

          <set>

              <value>AAA</value>

              <value>BBB</value>

              <value>CCC</value>

          </set>

      </property>

      <property name="myMap">

          <map>

              <entry key="name1" value="AAA"></entry>

              <entry key="name2" value="BBB"></entry>

              <entry key="name3" value="CCC"></entry>

          </map>

      </property>

      <property name="myProps">

          <props>

              <prop key="name1">AAA</prop>

              <prop key="name2">BBB</prop>

              <prop key="name3">CCC</prop>

          </props>

      </property>

  </bean>

創建Client5測試

public class Client5 {

public static void main(String[] args) {

//加載配置文件,獲取spring工廠,從容器中獲取dao和service的實現類

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

//從容器中獲取service

IAccountService accountService = (IAccountService) ac.getBean("accountService5");

accountService.saveAccount();

}

}

 

 

基於註解的IOC配置[掌握]——重點:18大註解標籤

明確:寫在最前

        學習基於註解的IoC配置,大家腦海裏首先得有一個認知,即註解配置和xml配置要實現的功能都是一樣的,都是要降低程序間的耦合。只是配置的形式不一樣。

        關於實際的開發中到底使用xml還是註解,每家公司有不同的習慣。所以這兩種配置方式我們都需要掌握。

 

1、用於裝配Bean的註解

@Component (value=”xxx”):

作用:

在類上使用該註解,把資源讓spring來管理。相當於在xml中配置一個bean。

屬性:

value:指定bean的id。如果不指定value屬性,默認bean的id是當前類的類名。首字母小寫。

/**

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

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

*/

@Component(value="accountService")

public class AccountServiceImpl implements IAccountService {

}

 

 

@Component的三個衍生註解:

@Controller(value=”xxx”):

         一般用於將web層裝配到容器中,使用方法和@Component(value=”xxx”)一摸一樣

@Service(value=”xxx”):

         一般用於將web層裝配到容器中,使用方法和@Component(value=”xxx”)一摸一樣

@Repository(value=”xxx”):

         一般用於將web層裝配到容器中,使用方法和@Component(value=”xxx”)一摸一樣

 

 

2、 用於屬性注入的註解

@Autowired:

         只能按照bean類型注入,如果有多個類型匹配,默認將屬性名稱作爲id去容器中查找。

@Qualifier:

         一般和@Autowired配合使用,用來注入指定id的bean,做方法的參數中可以獨立使用  屬性:value:指定beanid

@Resource:

         用來注入指定id的bean類型,相當於@Autowired+@Qualifier   屬性name:指定beanid

@Value:

         只能注入基本類型等數據,不能注入bean類型,可以使用${}在資源文件中獲取數據,前提是,外部資源文件被加載

 

3、 作用域的

@Scope:

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

 

4、 生命週期相關的

@PostConstruct:

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

@PreDestroy:

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

 

 

關於Spring註解和XML的選擇問題

註解的優勢:

配置簡單,維護方便(我們找到類,就相當於找到了對應的配置)。

XML的優勢:

修改時,不用改源碼。

 

Spring管理Bean方式的比較:

 

5、 其他配置類相關的

@Configuration:

         聲明一個類爲配置類,用於替代applicationContext.xml的

@ComponentScan:

         用於開啓註解掃描的包

@Import:

         用於導入其他類的

@PropertySource:

         用於加載外部資源文件的

@Bean:

         用於將方法返回的bean類型的對象裝配到容器中

純註解案例

環境搭建

創建配置類

@Configuration

@ComponentScan("cn.itcast")

public class SpringConfiguration {



    @Bean(name="jdbcTemplate")

    public JdbcTemplate createJdbcTempalte(@Qualifier("dataSource") DataSource dataSource){

        return new JdbcTemplate(dataSource);

    }



    @Bean(name="dataSource")

    public DataSource createDataSource(){

        DruidDataSource dataSource = new DruidDataSource();

        dataSource.setDriverClassName("com.mysql.jdbc.Driver");

        dataSource.setUrl("jdbc:mysql://localhost:3306/heima37");

        dataSource.setUsername("root");

        dataSource.setPassword("root");

        return dataSource;

    }

}

測試

public class AccountControllerTest {



@Test

public void saveAccuont() {

ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);

AccountController accountController = (AccountController) ac.getBean("accountController");



Account account = new Account();

account.setName("admin11");

account.setMoney(1000f);



accountController.saveAccuont(account);

}



}

優化

在resources類的根目錄下創建properties資源文件:

jdbc.driverClass=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://localhost:3306/heima25

jdbc.username=root

jdbc.password=root

 

springConfiguration:

@Configuration//聲明這是一個配置類,用來代替xml的

@ComponentScan("cn.itcast")//開啓註解掃描

@Import(value={JdbcConfig.class})

public class SpringConfiguration {

}
//加載外部資源文件

@PropertySource(value = {"classpath:jdbc.properties"})

public class JdbcConfig {



    @Value("${jdbc.driverClass}")

    private String driverClassName;

    @Value("${jdbc.url}")

    private String url;

    @Value("${jdbc.username}")

    private String username;

    @Value("${jdbc.password}")

    private String password;





    @Bean(name="jdbcTemplate")

    public JdbcTemplate createJdbcTempalte(@Qualifier("dataSource") DataSource dataSource){

        return new JdbcTemplate(dataSource);

    }



    @Bean(name="dataSource")

    public DataSource createDataSource(){

        DruidDataSource dataSource = new DruidDataSource();

        dataSource.setDriverClassName(driverClassName);

        dataSource.setUrl(url);

        dataSource.setUsername(username);

        dataSource.setPassword(password);

        return dataSource;

    }

}

 

6、 Junit相關的

@RunWith:

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

        屬性:

            value:單獨配置時,value屬性名稱可以省略,配置SpringJUnit4ClassRunner.class來代替原來junit的運行器

@ContextConfiguration

         用於指定配置文件或者配置類的

        屬性:

            value[]:用來指定xml配置文件的路徑

            class[]: 用來指定配置類

    

Xml的配置步驟案例:

導入spring-test的座標: 此處需要注意的是,spring5及以上版本要求junit的版本必須是4.12及以上,否則用不了

<dependency>

    <groupId>org.springframework</groupId>

    <artifactId>spring-test</artifactId>

    <version>5.0.6.RELEASE</version>

</dependency>

測試

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = {"classpath:applicationContext.xml"})

public class AccountControllerTest {



@Autowired

private AccountController accountController;



@Test

public void saveAccuont() {



Account account = new Account();

account.setName("admin13");

account.setMoney(1000f);



accountController.saveAccuont(account);

}

}

 

純註解的配置步驟(配置類)

環境搭建

導入spring-test的座標

<dependency>

    <groupId>org.springframework</groupId>

    <artifactId>spring-test</artifactId>

    <version>5.0.6.RELEASE</version>

</dependency>

測試

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(classes = {SpringConfiguration.class})

public class AccountControllerTest {



@Autowired

private AccountController accountController;

@Test

public void saveAccuont() {


Account account = new Account();

account.setName("admin14");

account.setMoney(1000f);

accountController.saveAccuont(account);

}
}

 

附:Spring—ICO練習源碼

https://download.csdn.net/download/zhuyi2576947717/10679802

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章