spring2

Spring第二天

回顾:

  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;

 

public interface UserService {

  

   /**

    * 业务层:用户保存

    */

   public void saveUser();

  

}

  1. 创建UserService的实现类UserServiceImpl

package cn.itcast.service.impl;

 

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

      }

   }

}

 

转载于:https://my.oschina.net/u/3892666/blog/3070736

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值