spring2

Spring次日

回顧:mysql

  1. IOC:控制反轉,把對象的建立權利反轉給spring框架。
  2. IOC的做用:解耦
  3. Spring中的工廠:
    1. ApplicationContext
      1. ClassPathXmlApplicationContext
      2. FileSystemXmlApplicationContext
    2. BeanFactory
  1. spring的配置文件
    1. bean標籤
      1. id
      2. class
      3. scope:singleton/prototype
      4. init-method
      5. destroy-method
    2. import標籤
  2. Spring中生成bean的三種方式
    1. 無參構造
    2. 靜態工廠方式實例化
    3. 實例工廠方式實例化
  1. DI:依賴注入
    1. 構造方法注入
    2. Set方法注入:先找無參構造實例對象,再調用屬性的set方法注入值
      1. P命名空間的寫法
      2. SpEl的寫法
    3. 特殊類型的注入
      1. List/Array
      2. Set
      3. Map
      4.   Properties
  1. Spring IOC註解的快速入門
    1. 建立Java工程並導入jar包
  1. 須要導入IOC容器須要的6個jar包+spring-aop.jar

    1. 建立包結構並編寫Java類
  1. 建立UserService接口

package cn.itcast.service;spring

 

public interface UserService {sql

  

   /**數據庫

    * 業務層:用戶保存apache

    */session

   public void saveUser();app

  

}框架

  1. 建立UserService的實現類UserServiceImpl

package cn.itcast.service.impl;ide

 

import cn.itcast.service.UserService;單元測試

 

public class UserServiceImpl implements UserService {

 

   @Override

   public void saveUser() {

      System.out.println("業務層:用戶保存...");

   }

 

}

    1. 在Java類上添加註解
  1. 在UserServiceImpl實現類上添加註解@Component,至關於<bean id=」」 class=」」>,value屬性給bean指定id,value屬性的名字也能夠不寫

@Component("userService")

public class UserServiceImpl implements UserService{

 

   @Override

   public void saveUser() {

      System.out.println("業務層:用戶保存...");

   }

 

}

    1. 在applicationContext.xml中引入約束

在src目錄下,建立applicationContext.xml的配置文件,引入約束。注意:由於如今想使用註解,那麼引入的約束髮生了變化,須要context的約束。同時還要引入log4j.properties.

【提示】:約束能夠從spring開發文檔中拷貝,也能夠從筆記裏拷貝。若是從spring開發文檔中拷貝,能夠參考spring開發文檔的6.9節

添加完context約束以後的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"

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

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

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

        http://www.springframework.org/schema/context

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

     

</beans>

    1. 在applicationContext.xml中開啓註解掃描

在applicationContext.xml經過context:component-scan標籤開啓spring註解掃描,掃描時是以包範圍來掃描的:

<?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:context="http://www.springframework.org/schema/context"

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

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

        http://www.springframework.org/schema/context

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

      <!-- 開啓註解掃描 -->

      <context:component-scan base-package="cn.itcast.service.impl"></context:component-scan>

</beans>

    1. 編寫測試代碼
  1. 建立單元測試類TestIOC,在其中建立單元測試方法test1

/**

    * 測試註解

*/

@Test

public void test1(){

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

      UserService userService = (UserService) applicationContext.getBean("userService");

      userService.saveUser();

}

  1. Spring框架中bean管理的經常使用註解

Spring中用於管理bean的註解分爲四大類:

  1. 用於建立對象
  2. 用於給對象中的屬性注入值
  3. 用於改變做用範圍
  4. 用於定義生命週期
    1. 用於建立對象的(重點)

用於建立對象的有四個:@Component,@Controller,@Service,@Repository

      1. @Component註解

做用:

    把資源讓spring來管理。至關於在xml中配置一個bean。

屬性:

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

      1. @Controller @Service @Repository

他們三個註解都是針對一個的衍生註解,他們的做用及屬性都是如出一轍的。

他們只不過是提供了更加明確的語義化。

    @Controller通常用於表現層的註解。

    @Service通常用於業務層的註解。

    @Repository通常用於持久層的註解。

@Service的用法:修改UserServiceImpl類,把@Component改爲@Service

//@Component("userService")

@Service("userService")

public class UserServiceImpl implements UserService{

 

   @Override

   public void saveUser() {

      System.out.println("業務層:用戶保存...");

   }

 

}

@Repository的用法:

建立UserDao接口:

public interface UserDao {

 

   public void save();

  

}

建立UserDao接口的實現類UserDaoImpl,在該類上加@Repository註解

@Repository("userDao")

public class UserDaoImpl implements UserDao {

 

   @Override

   public void save() {

      System.out.println("持久層:用戶保存...");

   }

 

}

注意:此處測試時,要把掃描的包定義爲cn.itcast,否則的其它包的註解就不能識別了

<?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:context="http://www.springframework.org/schema/context"

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

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

        http://www.springframework.org/schema/context

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

      <!-- 開啓註解掃描 -->

      <context:component-scan base-package="cn.itcast"></context:component-scan>

</beans>

 

 

@Controller的用法:建立UserAction類,在該類上加@Controller註解

@Controller("userAction")

public class UserAction {

 

}

 

說明:這三個註解是爲了讓標註類自己的用途清晰

    1. 用於注入數據的

用於注入數據的註解有:

  1. @Value
  2. @Autowired
  3. @Qualifier
  4. @Resource

至關於:<property name="" ref="">        

              <property name="" value="">

      1. @Value

做用:

    注入基本數據類型和String類型數據的

屬性:

    value:用於指定值

修改UserServiceImpl類,增長一個字符串屬性name,如今要經過@Value給name屬性注入值

@Service("userService")

public class UserServiceImpl implements UserService {

  

   @Value("張三")

   private String name;

 

   @Override

   public void saveUser() {

      System.out.println("業務層:用戶保存..." + name);

   }

 

}

運行TestIOC中的test1方法,測試結果以下:

      1. @Autowired(重點)

做用:

    自動按照類型注入。當使用註解注入屬性時,set方法能夠省略。它只能注入其餘bean類型。當有多個類型匹配時,使用要注入的對象變量名稱做爲bean的id,在spring容器查找,找到了也能夠注入成功。找不到就報錯。

修改UserServiceImpl類,增長一個對象屬性userDao,如今經過@Autowired給userDao注入值

@Service("userService")

public class UserServiceImpl implements UserService {

  

   @Value("張三")

   private String name;

  

   @Autowired

   private UserDao userDao;

 

   @Override

   public void saveUser() {

      System.out.println("業務層:用戶保存..." + name);

      userDao.save();

   }

 

}

運行TestIOC中的test1方法,測試結果以下:

      1. @Qualifer

做用:

    在自動按照類型注入的基礎之上,再按照Bean的id注入。它在給字段注入時不能獨立使用,必須和@Autowire一塊兒使用;可是給方法參數注入時,能夠獨立使用。

屬性:

    value:指定bean的id。

 

  1. 建立UserDao接口的第二個實現類UserDaoImpl2

@Repository("userDao2")

public class UserDaoImpl2 implements UserDao {

 

   @Override

   public void save() {

      System.out.println("持久層:用戶保存2222...");

   }

}

運行TestIOC中的test1方法,測試結果以下:

 

  1. 測試發現,UserServiceImpl中注入的仍是第一個UserDaoImpl,由於當有多個bean都知足的狀況下,優先注入bean的id與屬性的名字同樣的bean;想指定注入UserDaoImpl2,須要使用@Qualifier註解根據名字來注入

@Service("userService")

public class UserServiceImpl implements UserService {

  

   @Value("張三")

   private String name;

  

   @Autowired

   @Qualifier("userDao2")

   private UserDao userDao;

 

   @Override

   public void saveUser() {

      System.out.println("業務層:用戶保存..." + name);

      userDao.save();

   }

 

}

再次運行TestIOC中的test1方法,發現UserServiceImpl中注入的是UserDaoImpl2;測試結果以下:

 

      1. @Resource

做用:

    直接按照Bean的id注入。它也只能注入其餘bean類型。

屬性:

    name:指定bean的id。

修改UserServiceImpl類,使用@Resource給userDao注入值。@Resource是按照bean的id來注入,只能注入對象類型

@Service("userService")

public class UserServiceImpl implements UserService {

  

   @Value("張三")

   private String name;

  

// @Autowired

// @Qualifier("userDao2")

   @Resource(name="userDao2")

   private UserDao userDao;

 

   @Override

   public void saveUser() {

      System.out.println("業務層:用戶保存..." + name);

      userDao.save();

   }

 

}

 

    1. 用於改變做用域範圍的
      1. @Scope(重點)

做用:

    指定bean的做用範圍。

屬性:

    value:指定範圍的值。

           取值:singleton  prototype request session globalsession

 

  1. @Scope指定bean的做用域,默認值是singleton,單例的。
  1. 修改UserServiceImpl,在該類上加@Scope註解,指定該類是多例的的,默認是單例的。給該類顯示指定一個無參構造方法,方便測試

@Service("userService")

@Scope("prototype")

public class UserServiceImpl implements UserService{

  

   @Value("張三")

   private String name;

  

// @Autowired

// @Qualifier("userDao2")

   @Resource(name="userDao2")

   private UserDao userDao;

 

 

public UserServiceImpl() {

      System.out.println("調用了無參構造方法...");

   }

 

   @Override

   public void saveUser() {

      System.out.println("業務層:用戶保存..." + name);

      userDao.save();

   }

 

}

  1. 在TestIOC中建立test2單元測試方法

   @Test

   public void test2(){

      //建立ioc容器

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

      UserService userService1 = (UserService) ac.getBean("userService");

      UserService userService2 = (UserService) ac.getBean("userService");

      System.out.println(userService1 == userService2);

   }

  1. 測試發現:當scope指定爲prototype時,兩次獲取UserService的對象是不一致的。測試結果以下:

    1. 和生命週期相關的

至關於:<bean id="" class="" init-method="" destroy-method="" />

      1. @PostConstruct註解

@PostConstruct加在方法上,指定bean對象建立好以後,調用該方法初始化對象,相似於xml的init-method方法。修改UserServiceImpl類,在其中增長一個init方法,在該方法上指定@PostConstruct註解

@Service("userService")

public class UserServiceImpl implements UserService {

  

   @Value("張三")

   private String name;

  

// @Autowired

// @Qualifier("userDao2")

   @Resource(name="userDao2")

   private UserDao userDao;

  

   public UserServiceImpl() {

      System.out.println("調用了無參構造方法...");

   }

  

   @PostConstruct

   public void init(){

      System.out.println("調用了init方法...");

   }

 

   @Override

   public void saveUser() {

      System.out.println("業務層:用戶保存..." + name);

      userDao.save();

   }

}

運行TestIOC中的test1方法,測試結果以下:

      1. @PreDestory註解

@PreDestory加在方法上,指定bean銷燬以前,調用該方法,相似於xml的destory-method方法。修改UserServiceImpl類,在該類中增長一個destroy方法,在該方法上加@PreDestroy註解

@Service("userService")

public class UserServiceImpl implements UserService {

  

   @Value("張三")

   private String name;

  

// @Autowired

// @Qualifier("userDao2")

   @Resource(name="userDao2")

   private UserDao userDao;

  

   public UserServiceImpl() {

      System.out.println("調用了無參構造方法...");

   }

  

   @PostConstruct

   public void init(){

      System.out.println("調用了init方法...");

   }

 

   @Override

   public void saveUser() {

      System.out.println("業務層:用戶保存..." + name);

      userDao.save();

   }

  

   @PreDestroy

   public void destroy(){

      System.out.println("調用了destroy方法...");

   }

 

}

注意:要看到@PreDestory的效果,須要調用ClassPathXmlApplicationContext.close方法,同時scope的值要是singleton。因此,還得修改test1方法,顯示關閉ioc容器

@Test

   public void test1(){

      //建立ioc容器

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

      UserService userService = (UserService) ac.getBean("userService");

      userService.saveUser();

      ((ClassPathXmlApplicationContext)ac).close();

   }

測試結果以下:

  1. XML和註解的比較

註解的優點:

    配置簡單,維護方便。(咱們找到了類,就至關於找到了配置)

XML的優點:

    修改時,不用改源碼。不涉及從新編譯和部署。

 

Xml和註解的比較

  1. 案例:Spring整合DBUtils實現增刪改查
    1. 2第一步:建立工程,導入jar包

須要導入的jar包有:spring ioc必要的六個jar包+c3p0+mysql驅動包。完成的jar包以下圖所示:

    1. 第二步:建立業務層接口及實現類

建立Customer實體類

建立CustomerService接口

public interface CustomerService {

 

   /**

    * 業務層:查詢全部客戶

    * @return

    */

   public List<Customer> findAllCustomer();

  

}

建立CustomerService接口的實現類CustomerServiceImpl

public class CustomerServiceImpl implements CustomerService {

  

   private CustomerDao customerDao;

  

 

   public void setCustomerDao(CustomerDao customerDao) {

      this.customerDao = customerDao;

   }

 

 

   @Override

   public List<Customer> findAllCustomer() {

      List<Customer> list = customerDao.findAll();

      return list;

   }

 

}

    1. 第三步:建立dao層接口及實現類

建立UserDao接口

public interface CustomerDao {

 

   public List<Customer> findAll();

}

建立UserDao接口的實現類

public class CustomerDaoImpl implements CustomerDao {

  

   private QueryRunner queryRunner;//不須要實例化,經過spring依賴注入進來

  

 

   public void setQueryRunner(QueryRunner queryRunner) {

      this.queryRunner = queryRunner;

   }

 

 

   @Override

   public List<Customer> findAll() {

      List<Customer> list = null;

      try {

         list = queryRunner.query("select * from cst_customer", new BeanListHandler<Customer>(Customer.class));

      } catch (SQLException e) {

         e.printStackTrace();

      }

      return list;

   }

}

    1. 第四步:編寫spring配置文件

在src下建立spring的配置文件applicationContext.xml,把Service、Dao、QueryRunner、DataSource配置到Spring中

  1. Service中須要注入DAO
  2. DAO中須要注入QueryRunner
  3. QueryRunner中須要注入DataSource
  4. DataSource中須要注入驅動、鏈接地址、用戶名、密碼

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

       

        <bean id="customerService" class="cn.itcast.service.impl.CustomerServiceImpl">

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

        </bean>

         <bean id="customerDao" class="cn.itcast.dao.impl.CustomerDaoImpl">

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

        </bean

        <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">

          <constructor-arg name="ds" ref="dataSource"></constructor-arg>

        </bean>

        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">

          <property name="driverClass" value="com.mysql.jdbc.Driver"></property>

          <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/hibernate"></property>

          <property name="user" value="root"></property>

          <property name="password" value="123456"></property>

        </bean>

</beans>

注意:還得引入log4j.properties文件

    1. 第五步:編寫測試類

建立單元測試類TestFind,在其中建立test1方法

@Test

   public void test1(){

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

      CustomerService customerService = (CustomerService) ac.getBean("customerService");

      List<Customer> customers = customerService.findAllCustomer();

      for (Customer customer : customers) {

         System.out.println(customer);

      }

   }

在這裏測試的時候,實體類的屬性名字要和數據庫的屬性名字一一對應,否則數據不能回顯;

測試結果以下:

  1. 案例:採用註解把Spring和DBUtils進行整合

能夠把第四章的工程裏直接改爲註解的形式

    1. 第一步:導入spring-aop.jar

注意:註解開發須要額外導入spring-aop.jar

    1. 第二步:在類上加對應的註解

修改CustomerServiceImpl類,在該類上加@Service註解。在customerDao上加@Autowired註解,表示給該屬性注入值

@Service("customerService")

public class CustomerServiceImpl implements CustomerService {

  

   @Autowired

   private CustomerDao customerDao;

 

   @Override

   public List<Customer> findAllCustomer() {

      List<Customer> list = customerDao.findAllCustomer();

      return list;

   }

 

}

修改CustomerDaoImpl類,在該類上加@Repository註解。在queryRunner上加@Autowired註解,表示給該屬性注入值。

@Repository("customerDao")

public class CustomerDaoImpl implements CustomerDao {

  

   @Autowired

   private QueryRunner queryRunner;

  

 

   @Override

   public List<Customer> findAll() {

      List<Customer> list = null;

      try {

         list = queryRunner.query("select * from cst_customer", new BeanListHandler<Customer>(Customer.class));

      } catch (SQLException e) {

         e.printStackTrace();

      }

      return list;

   }

 

}

    1. 第三步:修改spring配置文件

在applicationContext.xml中開啓spring註解掃描。

注意:QueryRunner和DataSource這兩個bean暫時沒有辦法用註解來配置,由於屬於jar包裏的bean.

<?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:context="http://www.springframework.org/schema/context"

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

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

        http://www.springframework.org/schema/context

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

       

        <context:component-scan base-package="cn.itcast"></context:component-scan>

        <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">

          <constructor-arg name="ds" ref="dataSource"></constructor-arg>

        </bean>

        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">

          <property name="driverClass" value="com.mysql.jdbc.Driver"></property>

          <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/hibernate"></property>

          <property name="user" value="root"></property>

          <property name="password" value="123456"></property>

        </bean>

</beans>

再次運行TestFind中的test1方法,結果和xml的配置是同樣的。

  1. 案例:採用Spring全註解整合DBUtils

全註解整合的思路:要想實現全註解,得把applicationContext.xml的全部內容用一個類來配置。@Configuration註解能夠表示一個類是配置類;@ComponentScan註解能夠實現包掃描;還得想辦法把QueryRunner和DataSource這兩個bean用註解來配置。這個兩個bean都是來自於jar包中的,用傳統的註解配置方法是不可能實現的。得用@Bean註解,這個註解能夠把某個方法的返回值存放到spring容器中。咱們能夠寫兩個方法,這兩個方法分別返回QueryRunner對象和DataSource對象,而後在這兩個方法上加@Bean註解,就能夠保證spring容器中QueryRunner和DataSource這兩個對象了。

    1. 第一步:建立spring配置類

@Configuration//指定該類是spring的配置類,用來替換bean.xml

@ComponentScan("cn.itcast")//指定要掃描的包

public class SpringConfig {

 

   /**

    * Bean註解:把方法的返回值交給srping容器來管理

    * @param ds

    * @return

    */

   @Bean(name="queryRunner")

   public QueryRunner createQueryRunner(@Qualifier("dataSource") DataSource ds){

      return new QueryRunner(ds);

   }

  

   @Bean(name="dataSource")

   public DataSource createDataSource(){

      ComboPooledDataSource dataSource = new ComboPooledDataSource();

      try {

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

         dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/hibernate");

         dataSource.setUser("root");

         dataSource.setPassword("123456");

      } catch (PropertyVetoException e) {

         e.printStackTrace();

      }

      return dataSource;

   }

}

    1. 第二步:修改測試代碼

由於已經用SpringConfig類來代替applicationContext.xml了,因此,得更換ApplicationContext接口的實現類爲AnnotationConfigApplicationContext

@Test

   public void test1(){

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

      ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);

      CustomerService customerService = (CustomerService) ac.getBean("customerService");

      List<Customer> customers = customerService.findAllCustomer();

      for (Customer customer : customers) {

         System.out.println(customer);

      }

   }

運行test1方法,發現結果和以前是一致的。

    1. 第三步:把數據庫鏈接相關的bean放到JdbcConfig類中

下面,能夠考慮優化SpringConfig配置類。在SpringConfig類中可能會出現不少方法,能夠考慮實現分離。建立另外一個配置類JdbcConfig,把createQueryRunner和createDataSource方法挪到JdbcConfig中:

public class JdbcConfig {

  

   /**

    * Bean註解:把方法的返回值交給srping容器來管理

    * @param ds

    * @return

    */

   @Bean(name="queryRunner")

   public QueryRunner createQueryRunner(@Qualifier("dataSource") DataSource ds){

      return new QueryRunner(ds);

   }

  

   @Bean(name="dataSource")

   public DataSource createDataSource(){

      ComboPooledDataSource dataSource = new ComboPooledDataSource();

      try {

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

         dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/hibernate");

         dataSource.setUser("root");

         dataSource.setPassword("123456");

      } catch (PropertyVetoException e) {

         e.printStackTrace();

      }

      return dataSource;

   }

}

 

在SpringConfig中引入JdbcConfig

@Configuration//指定該類是spring的配置類,用來替換bean.xml

@ComponentScan("cn.itcast")//指定要掃描的包

@Import(JdbcConfig.class)

public class SpringConfig {

 

 

}

    1. 第四步:把數據庫鏈接信息寫到配置文件中

此時,咱們發現,數據庫的驅動類名、鏈接地址、用戶名、密碼都是直接寫死在類中的,不便於修改,能夠把與數據庫相關的信息寫到jdbc.properties中。在src下建立jdbc.properties文件:

jdbc.properties內容以下:

jdbc.driverClass=com.mysql.jdbc.Driver

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

jdbc.username=root

jdbc.password=123456

    1. 第五步:在JdbcConfig中採用佔位符讀取配置文件中的信息

修改JdbcConfig,定義四個成員變量,在每一個成員變量上加@value註解,爲該變量注入值,值來自於jdbc.properties.${}中寫的是jdbc.properties中的鍵。

public class JdbcConfig {

  

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

   private String driverClass;

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

   private String jdbcUrl;

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

   private String username;

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

   private String password;

 

   @Bean(name="queryRunner")//把該方法的返回值放到ioc容器中,等價於<bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">

   public QueryRunner createQueryRunner(@Qualifier("dataSource") DataSource ds){

      return new QueryRunner(ds);

   }

  

   @Bean(name="dataSource")//把該方法的返回值放到ioc容器中,  <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">

   public DataSource createDataSource(){

      ComboPooledDataSource dataSource = new ComboPooledDataSource();

      try {

         dataSource .setDriverClass(driverClass);

         dataSource .setJdbcUrl(jdbcUrl);

         dataSource .setUser(username);

         dataSource .setPassword(password);

      } catch (PropertyVetoException e) {

         e.printStackTrace();

      }

      return ds;

   }

}

 

    1. 第六步:在SpringConfig中配置佔位符解析器

在SpringConfig中須要經過@PropertySource註解引入外部屬性文件jdbc.properties;還要在SpringConfig類中配置一個佔位符$的解析器,這樣才能解析${jdbc.username}這樣的表達式

@Configuration//指定該類是spring的配置類,用來替換bean.xml

@ComponentScan("cn.itcast")//指定要掃描的包

@Import(JdbcConfig.class)

@PropertySource("classpath:cn/itcast/config/jdbc.properties")

public class SpringConfig {

 

   @Bean

   public PropertySourcesPlaceholderConfigurer createPropertySourcesPlaceholderConfigurer(){

      return new PropertySourcesPlaceholderConfigurer();

   }

}

最後,再次運行test1方法進行測試。

  1. Spring框架整合JUnit單元測試
    1. 目的

爲了簡化了JUnit的測試,使用Spring框架也能夠整合測試。

    1. 具體步驟

要求:必須先有JUnit的環境(默認會使用Eclipse導入單元測試的環境)!!

      1. 步驟一:在程序中引入spring-test.jar

能夠直接在spring4_day02中引入spring-test.jar包,把spring4_day02中的單元測試類所有改爲spring的寫法

注意:spring單元測試還得要有spring-aop.jar包,由於spring單元測試會用到註解

      1. 步驟二:在具體測試類上添加註解

修改單元測試類TestIOC,在該類上添加@RunWith和@ContextConfiguration兩個註解。咱們須要測試的是UserService,在TestIOC中聲明一個UserService的屬性,並在該屬性上添加@Autowired註解,爲該屬性注入值。修改後的TestIOC以下:

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration("classpath:applicationContext.xml")

public class TestIOC {

  

   @Autowired

   private UserService userService;

  

   @Test

   public void test1(){

      userService.saveUser();

   }

  

}

  1. @RunWith註解:這個是指定使用的單元測試執行類,這裏就指定的是SpringJUnit4ClassRunner.class;
  2. @ContextConfiguration註解:這個指定spring配置文件所在的路徑,能夠同時指定多個文件;
    1. 純註解的形式整合JUnit

spring4_day02_springAndDBUtilsFullAnnotation這個工程是一個全註解的工程,沒有applicaitonContext.xml文件,那麼@ContextConfiguration註解就沒辦法指定applicationContext.xml了,只能指定SpringConfig這個配置類了。@ContextConfiguration中的classes屬性指定配置類。修改TestFind單元測試類以下:

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(classes=SpringConfig.class)//指定加載配置類建立ioc容器

public class TestFind {

 

   @Autowired

   private CustomerService customerService;

  

   @Test

   public void test1(){

      List<Customer> list = customerService.findAllCustomer();

      for (Customer customer : list) {

         System.out.println(customer);

      }

   }

}

相關文章
相關標籤/搜索