spring IOC

学习目标

  • 能够编写spring的IOC注解代码

  • 能够使用spring实现包扫描注解配置

  • 能够说出spring的IOC常用注解含义

  • 能够实现spring纯xml配置IOC的案例

  • 能够实现spring基于xml和注解配置IOC的案例

  • 了解spring纯注解配置IOC案例

  • 能够实现spring整合单元测试框架junit

spring的IOC常用注解

写在前面

今天使用注解实现spring 的IOC配置,相关的概念和原理,与spring IOC第一天的内容一致。只是实现方式从使用xml配置(bean.xml),转换成注解配置,并且我们会从完全使用xml配置方式,到xml和注解混合使用配置方式,再到完全使用注解配置方式的演化。

注解配置入门体验

创建项目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K75btXdN-1582257206299)(media/5e89855291acc8c973c96c697ffd4700.png)]

编写项目中的业务层和持久层对象

编写持久层对象
  • 客户dao接口
package cn.itheima.dao;

/**
 * 客户dao接口
 */
public interface CustomerDao {

    /**
     * 保存客户
     */
    void saveCustomer();
}

  • 客户dao实现类
package cn.itheima.dao.impl;

import cn.itheima.dao.CustomerDao;

/**
 * 客户dao实现类
 */
public class CustomerDaoImpl implements CustomerDao {
    /**
     * 保存客户
     */
    public void saveCustomer() {
        System.out.println("保存客户。");
    }
}

编写业务层对象
  • 客户service接口
package cn.itheima.service;

/**
 * 客户service接口
 */
public interface CustomerService {

    /**
     * 保存客户
     */
    void saveCustomer();
}

  • 客户service实现类
package cn.itheima.service.impl;

import cn.itheima.dao.CustomerDao;
import cn.itheima.service.CustomerService;

/**
 * 客户service实现类
 */
public class CustomerServiceimpl implements CustomerService {
    
    // 客户dao
    private CustomerDao customerDao;
    
    public void setCustomerDao(CustomerDao customerDao) {
        this.customerDao = customerDao;
    }

    /**
     * 保存客户
     */
    public void saveCustomer() {
        customerDao.saveCustomer();
    }
}

搭建spring IOC开发环境

配置pom.xml,加入ioc依赖包
<?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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.itheima</groupId>
    <artifactId>spring-day02-01annotation-helloworld</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>jar</packaging>

    <properties>
        <!--spring版本-->
        <spring.version>5.0.2.RELEASE</spring.version>
    </properties>

    <dependencies>
        <!--spring ioc依赖包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
    </dependencies>

</project>

编写bean.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">
    
    <!--配置客户service-->
    <bean id="customerService" class="cn.itheima.service.impl.CustomerServiceimpl">
        <!--注入客户dao-->
        <property name="customerDao" ref="customerDao"></property>
    </bean>
    
    <!--配置客户dao-->
    <bean id="customerDao" class="cn.itheima.dao.impl.CustomerDaoImpl"></bean>

</beans>

编写项目表现层对象

package cn.itheima.controller;

import cn.itheima.service.CustomerService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 客户表现层对象
 */
public class CustomerController {

    public static void main(String[] args) {
        // 1.加载spring配置文件,创建spring容器
        /**
         * classpath:==》表示从类的根路径下加载配置文件,可以加也可以不加。
         * spring框架建议我们加上。
         */
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean.xml");

        // 2.从spring容器中,获取客户service对象
        CustomerService customerService = (CustomerService) context.getBean("customerService");

        // 3.保存客户
        customerService.saveCustomer();
    }
}

测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wMpka8iq-1582257206301)(media/ea70b397a15577b4289b665a1d1ac0bf.png)]

注解入门配置

改造客户dao实现类

package cn.itheima.dao.impl;

import cn.itheima.dao.CustomerDao;
import org.springframework.stereotype.Component;

/**
 * 客户dao实现类
 */
@Component("customerDao")
public class CustomerDaoImpl implements CustomerDao {
    /**
     * 保存客户
     */
    public void saveCustomer() {
        System.out.println("保存客户。");
    }
}

改造客户service实现类

package cn.itheima.service.impl;

import cn.itheima.dao.CustomerDao;
import cn.itheima.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 客户service实现类
 */
@Component("customerService")
public class CustomerServiceimpl implements CustomerService {

    // 客户dao
    @Autowired
    private CustomerDao customerDao;

    /*public void setCustomerDao(CustomerDao customerDao) {
        this.customerDao = customerDao;
    }*/

    /**
     * 保存客户
     */
    public void saveCustomer() {
        customerDao.saveCustomer();
    }
}

配置bean.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">

    <!--说明:
        1.客户service实现类和dao实现类,使用注解以后,只需要配置扫描包即可。
        2.配置步骤:
            第一步:导入context名称空间
            第二步:通过context:component-scan标签,配置扫描包。spring在创建容器的
            时候,会扫描指定的包和它的子包
    -->
    <context:component-scan base-package="cn.itheima"></context:component-scan>

</beans>
测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YMQEYeKM-1582257206301)(media/3ec45ad08a6ab3d5df19d17da9a7d618.png)]

常用注解分类

创建对象相关注解【掌握】

@Component

作用:

相当于bean.xml中的bean标签

属性:

value:给bean取一个唯一标识名称,相当于bean标签id属性

细节:

  1. value属性可以省略

  2. 默认使用类的名称首字母小写,作为bean的名称

案例演示
创建项目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZdOhgdZe-1582257206302)(media/a0cd4b7f3deeb75deab0e638f0b4537e.png)]

案例代码
package cn.itheima.service.impl;

import cn.itheima.dao.CustomerDao;
import cn.itheima.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 客户service实现类
 *
 * 常用注解分类:
 *      1.创建对象相关注解:
 *          @Component:
 *              作用:相当于bean.xml中的bean标签
 *              属性:
 *                  value:给bean取一个唯一标识名称,相当于bean标签的id属性
 *               细节:
 *                  1.value属性可以省略
 *                  2.默认使用类的名称首字母小写,作为bean的名称
 *
 */
@Component("customerService")
public class CustomerServiceimpl implements CustomerService {

    // 客户dao
    @Autowired
    private CustomerDao customerDao;

    /**
     * 保存客户
     */
    public void saveCustomer() {
        customerDao.saveCustomer();
    }
}
@Controller @Service @Repository

说明:这三个注解,都是由@Component衍生的注解。衍生的目的是让语义更加明确。

@Controller:一般用于表现层对象

@Service:一般用于业务层对象

@Repository:一般用于持久层对象

案例代码
package cn.itheima.service.impl;

import cn.itheima.dao.CustomerDao;
import cn.itheima.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

/**
 * 客户service实现类
 *
 * 常用注解分类:
 *      1.创建对象相关注解:
 *          @Component:
 *              作用:相当于bean.xml中的bean标签
 *              属性:
 *                  value:给bean取一个唯一标识名称,相当于bean标签的id属性
 *               细节:
 *                  1.value属性可以省略
 *                  2.默认使用类的名称首字母小写,作为bean的名称
 *
 *          @Controller  @Service  @Repository
 *           说明:这三个注解是由@Component注解衍生而来,衍生的目的是让语义更加明确。
 *           @Controller:一般用于表现层对象
 *           @Service:一般用于业务层对象
 *           @Repository:一般用于持久层对象
 *
 *
 */
//@Component("customerService")
@Service("customerService")
public class CustomerServiceimpl implements CustomerService {

    // 客户dao
    @Autowired
    private CustomerDao customerDao;

    /**
     * 保存客户
     */
    public void saveCustomer() {
        customerDao.saveCustomer();
    }
}

设置bean作用范围相关注解【掌握】

@Scope

作用:

相当于bean标签的scope属性

属性:

value:指定作用范围取值

属性取值:

singleton:单例。默认值

prototype:多例

request:web项目中,把bean对象存入request域中【了解】

session:web项目中,把bean对象存入session域中【了解】

globalsession:web项目中,把bean对象存入全局session域中【了解】

案例代码
package cn.itheima.service.impl;

import cn.itheima.dao.CustomerDao;
import cn.itheima.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

/**
 *
 *      2.设置bean作用范围相关注解:
 *          @Scope:
 *              作用:相当于bean标签中scope属性
 *              属性:
 *                  value:指定bean作用范围取值
 *              属性取值:
 *                  singleton:单例。默认值
 *                  prototype:多例
 *                  request:web项目中,把beabn对象存入request域中【了解】
 *                  session:web项目中,把bean对象存入session域中【了解】
 *                  globalsession:web项目中,把bean对象存入全局session域中【了解】
 *
 */
//@Component("customerService")
@Service("customerService")
@Scope("singleton")
public class CustomerServiceimpl implements CustomerService {

    // 客户dao
    @Autowired
    private CustomerDao customerDao;

    /**
     * 保存客户
     */
    public void saveCustomer() {
        customerDao.saveCustomer();
    }
}

注入数据相关注解【掌握】

@Autowired

作用:

默认按照bean的类型注入数据

细节:

1.在spring容器中,如果同一个类型存在多个bean实例对象。则先按照bean的类型进行注入,再按照bean的名称进行匹配。匹配上注入成功;否则注入失败。

案例代码
package cn.itheima.service.impl;

import cn.itheima.dao.CustomerDao;
import cn.itheima.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

/**
 *
 *      3.注入数据相关注解:
 *          @Autowired:
 *              作用:默认按照bean的类型注入数据
 *              细节:
 *                  1.在spring容器中,同一个类型存在多个bean实例对象。先按照bean的类型注入,再按照bean的名称进行匹配。
 *                  匹配上注入成功;匹配不上注入失败。
 */
//@Component("customerService")
@Service("customerService")
@Scope("singleton")
public class CustomerServiceimpl implements CustomerService {

    // 客户dao
    @Autowired
    private CustomerDao customerDao;

    /**
     * 保存客户
     */
    public void saveCustomer() {
        customerDao.saveCustomer();
    }
}

@Qualifier(配合@Autowired一起使用)

作用:配合@Autowired注解一起使用,在按照bean类型注入的基础上,再按照bean的名称注入

细节:

  1. 在成员变量上不能单独使用,需要配合@Autowired注解一起使用

  2. 在方法形参上可以单独使用

案例代码
package cn.itheima.service.impl;

import cn.itheima.dao.CustomerDao;
import cn.itheima.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

/** 3.注入数据相关注解:
 *          @Autowired:
 *              作用:默认按照bean的类型注入数据
 *              细节:
 *                  1.在spring容器中,同一个类型存在多个bean实例对象。先按照bean的类型注入,再按照bean的名称进行匹配。
 *                  匹配上注入成功;匹配不上注入失败。
 *
 *          @Qualifier:
 *              作用:配合@Autowired注解使用。在按照bean的类型注入基础上,再按照bean的名称进行注入。
 *              细节:
 *                  1.在成员变量上不能单独使用,需要配合@Autowired注解一起使用
 *                  2.在方法形参上可以单独使用
 *
 */
//@Component("customerService")
@Service("customerService")
@Scope("singleton")
public class CustomerServiceimpl implements CustomerService {

    // 客户dao
    @Autowired
    @Qualifier("customerDao")
    private CustomerDao customerDao1;

    /**
     * 保存客户
     */
    public void saveCustomer() {
        customerDao1.saveCustomer();
    }
}
@Resource(推荐使用)

作用:

默认按照bean的名称注入数据

属性:

name:指定bean的名称注入数据

type:指定bean的类型注入数据

细节:

默认按照bean的名称匹配注入数据。如果注入失败,再按照bean的类型注入。

案例代码
package cn.itheima.service.impl;

import cn.itheima.dao.CustomerDao;
import cn.itheima.dao.impl.CustomerDaoImpl;
import cn.itheima.dao.impl.CustomerDaoImpl2;
import cn.itheima.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 *          @Resource:
 *              作用:默认按照bean的名称注入数据
 *              属性:
 *                  name:指定bean的名称注入数据
 *                  type:指定按照bean的类型注入数据
 *              细节:
 *                  默认按照bean的名称注入数据。如果注入失败,再按照bean的类型注入数据
 *
 */
//@Component("customerService")
@Service("customerService")
@Scope("singleton")
public class CustomerServiceimpl implements CustomerService {

    // 客户dao
   /* @Autowired
    @Qualifier("customerDao2")*/

    //@Resource
    //@Resource(name="customerDao")
    @Resource(type= CustomerDaoImp.class)
    private CustomerDao customerDao1;

    /**
     * 保存客户
     */
    public void saveCustomer() {
        customerDao1.saveCustomer();
    }
}

@Value

作用:给java简单类型注入数据

案例代码
package cn.itheima.service.impl;

import cn.itheima.dao.CustomerDao;
import cn.itheima.dao.impl.CustomerDaoImpl;
import cn.itheima.dao.impl.CustomerDaoImpl2;
import cn.itheima.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/** 3.注入数据相关注解:
 *          @Autowired:
 *              作用:默认按照bean的类型注入数据
 *              细节:
 *                  1.在spring容器中,同一个类型存在多个bean实例对象。先按照bean的类型注入,再按照bean的名称进行匹配。
 *                  匹配上注入成功;匹配不上注入失败。
 *
 *          @Qualifier:
 *              作用:配合@Autowired注解使用。在按照bean的类型注入基础上,再按照bean的名称进行注入。
 *              细节:
 *                  1.在成员变量上不能单独使用,需要配合@Autowired注解一起使用
 *                  2.在方法形参上可以单独使用
 *
 *          @Resource:
 *              作用:默认按照bean的名称注入数据
 *              属性:
 *                  name:指定bean的名称注入数据
 *                  type:指定按照bean的类型注入数据
 *              细节:
 *                  默认按照bean的名称注入数据。如果注入失败,再按照bean的类型注入数据
 *
 *           @Value:
 *              作用:给java简单类型注入数据。
 *
 */
//@Component("customerService")
@Service("customerService")
@Scope("singleton")
public class CustomerServiceimpl implements CustomerService {

    // 客户dao
   /* @Autowired
    @Qualifier("customerDao")*/

    //@Resource
    //@Resource(name="customerDao")
    @Resource(type= CustomerDaoImp.class)
    private CustomerDao customerDao1;

    @Value("1")
    private int id;
    @Value("小花")
    private String name;

    /**
     * 保存客户
     */
    public void saveCustomer() {
        System.out.println("id:"+id+",name:"+name);
        customerDao1.saveCustomer();
    }
}

与bean生命周期相关注解【了解】

@PostConstruct

作用:指定执行初始化操作方法。相当于bean标签中的init-method属性。

@PreDestroy

作用:指定执行销毁操作方法。相当于bean标签中的destroy-method属性。

案例代码
package cn.itheima.service.impl;

import cn.itheima.dao.CustomerDao;
import cn.itheima.dao.impl.CustomerDaoImpl;
import cn.itheima.dao.impl.CustomerDaoImpl2;
import cn.itheima.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

/**    3.注入数据相关注解:
 *          @Autowired:
 *              作用:默认按照bean的类型注入数据
 *              细节:
 *                  1.在spring容器中,同一个类型存在多个bean实例对象。先按照bean的类型注入,再按照bean的名称进行匹配。
 *                  匹配上注入成功;匹配不上注入失败。
 *
 *          @Qualifier:
 *              作用:配合@Autowired注解使用。在按照bean的类型注入基础上,再按照bean的名称进行注入。
 *              细节:
 *                  1.在成员变量上不能单独使用,需要配合@Autowired注解一起使用
 *                  2.在方法形参上可以单独使用
 *
 *          @Resource:
 *              作用:默认按照bean的名称注入数据
 *              属性:
 *                  name:指定bean的名称注入数据
 *                  type:指定按照bean的类型注入数据
 *              细节:
 *                  默认按照bean的名称注入数据。如果注入失败,再按照bean的类型注入数据
 *
 *           @Value:
 *              作用:给java简单类型注入数据。
 *
 *      4.与bean生命周期相关的注解:
 *          @PostConstruct:
 *              作用:指定执行初始化操作方法。相当于bean标签中的init-method属性
 *          @PreDestroy:
 *              作用:指定执行销毁操作方法。相当于bean标签中的destroy-method属性
 */
//@Component("customerService")
@Service("customerService")
@Scope("singleton")
public class CustomerServiceimpl implements CustomerService {

    // 客户dao
   /* @Autowired
    @Qualifier("customerDao")*/

    //@Resource
    //@Resource(name="customerDao")
    @Resource(type= CustomerDaoImp.class)
    private CustomerDao customerDao;

    @Value("1")
    private int id;
    @Value("小花")
    private String name;

    /**
     * 保存客户
     */
    public void saveCustomer() {
        System.out.println("id:"+id+",name:"+name);
        customerDao1.saveCustomer();
    }

    /**
     * 初始化方法
     */
    @PostConstruct
    public void init(){
        System.out.println("正在执行初始化操作。");
    }

    /**
     * 销毁方法
     */
    @PreDestroy
    public void destroy(){
        System.out.println("正在执行销毁操作。");
    }
}

spring注解方式配置IOC

需求

使用spring的JdbcTemplate+druid,实现查询全部客户列表数据。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DOmtOEZa-1582257206302)(media/1de2e3b898c3d80971a179d923de8ce4.png)]

需求实现

纯xml版本【掌握】

创建项目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9bKXULWP-1582257206303)(media/45c1536e3250b87658ddf6856959cbf4.png)]

配置pom.xml,加入依赖包

  • spring框架基础包(context、beans、core、expression)

  • spring框架jdbc包

  • 数据库连接池包(druid)

  • mysql数据库驱动包

<?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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.itheima</groupId>
    <artifactId>spring-day02-03case-xml</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>jar</packaging>

    <properties>
        <!--spring版本-->
        <spring.version>5.0.2.RELEASE</spring.version>
        <!--druid版本-->
        <druid.version>1.0.29</druid.version>
        <!--mysql驱动版本-->
        <mysql.version>5.1.6</mysql.version>
    </properties>

    <dependencies>
        <!--spring ioc依赖包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--spring jdbc包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--数据库连接池druid-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${druid.version}</version>
        </dependency>
        <!--mysql驱动包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>

    </dependencies>
    
</project>

编写客户实体类

package cn.itheima.po;

/**
 * 客户实体类对象
 */
public class Customer {

    private Long custId;
    private String custName;
    private String custSource;
    private String custIndustry;
    private String custLevel;
    private String custAddress;
    private String custPhone;

    public Long getCustId() {
        return custId;
    }

    public void setCustId(Long custId) {
        this.custId = custId;
    }

    public String getCustName() {
        return custName;
    }

    public void setCustName(String custName) {
        this.custName = custName;
    }

    public String getCustSource() {
        return custSource;
    }

    public void setCustSource(String custSource) {
        this.custSource = custSource;
    }

    public String getCustIndustry() {
        return custIndustry;
    }

    public void setCustIndustry(String custIndustry) {
        this.custIndustry = custIndustry;
    }

    public String getCustLevel() {
        return custLevel;
    }

    public void setCustLevel(String custLevel) {
        this.custLevel = custLevel;
    }

    public String getCustAddress() {
        return custAddress;
    }

    public void setCustAddress(String custAddress) {
        this.custAddress = custAddress;
    }

    public String getCustPhone() {
        return custPhone;
    }

    public void setCustPhone(String custPhone) {
        this.custPhone = custPhone;
    }

    public String toString() {
        return "Customer{" +
                "custId=" + custId +
                ", custName='" + custName + '\'' +
                ", custSource='" + custSource + '\'' +
                ", custIndustry='" + custIndustry + '\'' +
                ", custLevel='" + custLevel + '\'' +
                ", custAddress='" + custAddress + '\'' +
                ", custPhone='" + custPhone + '\'' +
                '}';
    }
}

编写RowMapper结果集映射对象

package cn.itheima.rowmapper;

import cn.itheima.po.Customer;
import org.springframework.jdbc.core.RowMapper;

import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 客户结果集映射对象
 */
public class CustomerRowMapper implements RowMapper<Customer> {
    
    public Customer mapRow(ResultSet rs, int i) throws SQLException {
        
        // 创建客户对象
        Customer customer = new Customer();

        customer.setCustId(rs.getLong("cust_id"));
        customer.setCustName(rs.getString("cust_name"));
        customer.setCustSource(rs.getString("cust_source"));
        customer.setCustIndustry(rs.getString("cust_industry"));
        customer.setCustLevel(rs.getString("cust_level"));
        customer.setCustAddress(rs.getString("cust_address"));
        customer.setCustPhone(rs.getString("cust_phone"));
        
        return customer;
    }
}

编写客户持久层对象

  • 编写客户dao接口
package cn.itheima.dao;

import cn.itheima.po.Customer;

import java.util.List;

/**
 * 客户dao接口
 */
public interface CustomerDao {

    /**
     * 查询全部客户列表
     */
    List<Customer> findAllCustomers();
}
  • 编写客户dao实现类
package cn.itheima.dao.impl;

import cn.itheima.dao.CustomerDao;
import cn.itheima.po.Customer;
import cn.itheima.rowmapper.CustomerRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;

/**
 * 客户dao实现类对象
 */
public class CustomerDaoImpl implements CustomerDao {

    // 定义JdbcTemplate
    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    /**
     * 查询全部客户列表
     */
    public List<Customer> findAllCustomers() {

        List<Customer> list = jdbcTemplate
                .query("select * from cst_customer", new CustomerRowMapper());
        
        return list;
    }
}

编写客户业务层对象

  • 编写客户service接口
package cn.itheima.service;

import cn.itheima.po.Customer;

import java.util.List;

/**
 * 客户service接口
 */
public interface CustomerService {

    /**
     * 查询全部客户列表
     */
    List<Customer> findAllCustomers();
}
  • 编写客户service实现类
package cn.itheima.service.impl;

import cn.itheima.dao.CustomerDao;
import cn.itheima.po.Customer;
import cn.itheima.service.CustomerService;

import java.util.List;

/**
 * 客户service实现类
 */
public class CustomerServiceImpl implements CustomerService {
    
    // 定义客户dao
    private CustomerDao customerDao;

    public void setCustomerDao(CustomerDao customerDao) {
        this.customerDao = customerDao;
    }

    /**
     * 查询全部客户列表
     */
    public List<Customer> findAllCustomers() {
        return customerDao.findAllCustomers();
    }
}

编写bean.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">

    <!--配置客户service-->
    <bean id="customerService" class="cn.itheima.service.impl.CustomerServiceImpl">
        <!--注入客户dao-->
        <property name="customerDao" ref="customerDao"></property>
    </bean>

    <!--配置客户dao-->
    <bean id="customerDao" class="cn.itheima.dao.impl.CustomerDaoImpl">
        <!--注入JdbcTemplate-->
        <property name="jdbcTemplate" ref="jdbcTemplate"></property>
    </bean>

    <!--配置JdbcTemplate-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--注入数据源对象-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--配置数据源对象DataSource-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <!--注入四个基本属性-->
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://127.0.0.1:3308/spring"></property>
        <property name="username" value="root"></property>
        <property name="password" value="admin"></property>

        <!--数据库连接池常用属性-->
        <!-- 初始化连接数量 -->
        <property name="initialSize" value="6" />
        <!-- 最小空闲连接数 -->
        <property name="minIdle" value="3" />
        <!-- 最大并发连接数(最大连接池数量) -->
        <property name="maxActive" value="50" />
        <!-- 配置获取连接等待超时的时间 -->
        <property name="maxWait" value="60000" />
        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="60000" />
    </bean>

</beans>
编写客户表现层对象
package cn.itheima.controller;

import cn.itheima.po.Customer;
import cn.itheima.service.CustomerService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

/**
 * 客户表现层对象
 */
public class CustomerController {

    public static void main(String[] args) {
        // 1.加载spring配置文件,创建spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean.xml");

        // 2.获取客户service对象
        CustomerService customerService = (CustomerService) context.getBean("customerService");

        // 3.查询全部客户列表数据
        List<Customer> list = customerService.findAllCustomers();
        for(Customer c:list){
            System.out.println(c);
        }
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xq99QZZK-1582257206303)(media/b04e06d4abf38c93eca5e4ee49034ff7.png)]

xml与注解混合版本【掌握】

说明:上一个xml版本中,我们完整的实现了案例需求。接下来结合注解配置,完成xml与注解的混合使用。那么我们的思路在哪里呢?

实现思路:

  1. 把自定义的对象(客户service、客户dao),使用注解方式进行配置

  2. 把第三方提供的对象(JdbcTemplate、DataSource),使用xml方式进行配置

创建项目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rmlF86yt-1582257206303)(media/d6bc2080307a861e3304ef3bc40a01e0.png)]

改造客户dao实现类

package cn.itheima.dao.impl;

import cn.itheima.dao.CustomerDao;
import cn.itheima.po.Customer;
import cn.itheima.rowmapper.CustomerRowMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * 客户dao实现类对象
 */
@Repository("customerDao")
public class CustomerDaoImpl implements CustomerDao {

    // 定义JdbcTemplate
    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 查询全部客户列表
     */
    public List<Customer> findAllCustomers() {

        List<Customer> list = jdbcTemplate
                .query("select * from cst_customer", new CustomerRowMapper());

        return list;
    }
}

改造客户service实现类

package cn.itheima.service.impl;

import cn.itheima.dao.CustomerDao;
import cn.itheima.po.Customer;
import cn.itheima.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 客户service实现类
 */
@Service("customerService")
public class CustomerServiceImpl implements CustomerService {

    // 定义客户dao
    @Autowired
    private CustomerDao customerDao;

    /**
     * 查询全部客户列表
     */
    public List<Customer> findAllCustomers() {
        return customerDao.findAllCustomers();
    }
}

配置bean.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">

    <!--配置包扫描service、dao,说明:
        第一步:导入context名称空间
        第二步:通过context:component-scan标签,配置包扫描。spring创建容器的时候,
        会扫描指定的包和它的子包
    -->
    <context:component-scan base-package="cn.itheima"></context:component-scan>

    <!--配置JdbcTemplate-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--注入数据源对象-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--配置数据源对象DataSource-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <!--注入四个基本属性-->
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://127.0.0.1:3308/spring"></property>
        <property name="username" value="root"></property>
        <property name="password" value="admin"></property>

        <!--数据库连接池常用属性-->
        <!-- 初始化连接数量 -->
        <property name="initialSize" value="6" />
        <!-- 最小空闲连接数 -->
        <property name="minIdle" value="3" />
        <!-- 最大并发连接数(最大连接池数量) -->
        <property name="maxActive" value="50" />
        <!-- 配置获取连接等待超时的时间 -->
        <property name="maxWait" value="60000" />
        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="60000" />
    </bean>

</beans>

测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dHDCT0UL-1582257206303)(media/b238076d68bb04d39499e78f27cbe255.png)]

纯注解版本【了解】

说明:在注解与xml实现案例版本中,已经将客户service和dao实现类对象使用注解进行配置。但还是保留了bean.xml文件,在bean.xml中配置了扫描包、JdbcTemplate、DataSource对象。接下来我们将bean.xml中的内容也使用注解方式配置。即纯注解的案例版本。

这里需要思考一个问题:目前创建spring的容器入口是bean.xml文件,那么纯注解版本中,创建spring的容器入口在哪儿呢?

答案是:编写一个java类,作为spring的配置类,该配置类的作用相当于bean.xml文件。

创建项目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xZs0n1Eg-1582257206304)(media/175731ea8a57381e701e4413ca3bbbdb.png)]

编写配置类

package cn.itheima.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;

/**
 * spring配置类:相当于bean.xml文件
 *
 * 注解说明:
 *      1.@Configuration:标记当前java类,是一个spring的配置类
 *      2.@ComponentScan:配置扫描包。相当于xml配置中的context:component-scan标签
 */
@Configuration
@ComponentScan(value = {"cn.itheima"})
public class SpringConfiguration {

    /**
     *  <!--配置JdbcTemplate-->
     *<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
     *<!--注入数据源对象-->
     *<property name="dataSource" ref="dataSource"></property>
     *</bean>
     *
     * 说明:
     *   1.创建一个JdbcTemplate对象
     *   2.给该JdbcTemplate对象,注入一个数据源对象DataSource
     *   3.把该JdbcTemplate对象,以jdbcTemplate作为bean的名称,放入spring容器中
     *
     *   注解:
     *      @Bean:
     *          作用:把方法的返回值对象,放入spring容器中
     *          属性:
     *              value:给bean取一个唯一标识名称
     *              name:给bean取一个唯一标识名称
     */
    @Bean(value="jdbcTemplate")
    public JdbcTemplate createJdbcTemplate(DataSource dataSource){
        // 创建JdbcTemplate对象
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);

        return jdbcTemplate;
    }

    /**
     * <!--配置数据源对象DataSource-->
     *  <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
     *  <!--注入四个基本属性-->
     *  <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
     * <property name="url" value="jdbc:mysql://127.0.0.1:3308/spring"></property>
     *  <property name="username" value="root"></property>
     * <property name="password" value="admin"></property>

     *  <!--数据库连接池常用属性-->
     * <!-- 初始化连接数量 -->
     * <property name="initialSize" value="6" />
     * <!-- 最小空闲连接数 -->
     * <property name="minIdle" value="3" />
     *  <!-- 最大并发连接数(最大连接池数量) -->
     * <property name="maxActive" value="50" />
     * <!-- 配置获取连接等待超时的时间 -->
     * <property name="maxWait" value="60000" />
     * <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
     * <property name="timeBetweenEvictionRunsMillis" value="60000" />
     * </bean>
     */
    @Bean(name="dataSource")
    public DataSource createDataSource(){
        // 创建DataSource
        DruidDataSource dataSource = new DruidDataSource();

        // 注入属性
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://127.0.0.1:3308/spring");
        dataSource.setUsername("root");
        dataSource.setPassword("admin");

        dataSource.setInitialSize(6);
        dataSource.setMinIdle(3);
        dataSource.setMaxActive(50);
        dataSource.setMaxWait(60000);
        dataSource.setTimeBetweenEvictionRunsMillis(60000);

        return dataSource;
    }


}

改造客户表现层对象

package cn.itheima.controller;

        import cn.itheima.config.SpringConfiguration;
        import cn.itheima.po.Customer;
        import cn.itheima.service.CustomerService;
        import org.springframework.context.ApplicationContext;
        import org.springframework.context.annotation.AnnotationConfigApplicationContext;
        import org.springframework.context.support.ClassPathXmlApplicationContext;

        import java.util.List;

/**
 * 客户表现层对象
 */
public class CustomerController {

    public static void main(String[] args) {
        // 1.加载spring配置类,创建spring容器
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfiguration.class);

        // 2.获取客户service对象
        CustomerService customerService = (CustomerService) context.getBean("customerService");

        // 3.查询全部客户列表数据
        List<Customer> list = customerService.findAllCustomers();
        for(Customer c:list){
            System.out.println(c);
        }
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HayYJyNu-1582257206304)(media/b50e17eeb8389bc4675a8eab9a70f797.png)]

注解说明

注解作用
@Configuration标记当前java类,是spring配置类
@ComponentScan配置扫描包,相当于xml文件这的context:component-scan标签
@Bean将方法返回值对象,放入spring容器中

纯注解版本-优化版本【掌握】

在上一个纯注解配置的版本中,有两个方面的问题需要解决:

  • 所有对象都配置到SpringConfiguration类中,内容太多,不好维护

  • 数据源DataSource配置,连接数据库的四个基本要素和其它连接池信息,直接在java代码中写死了,是硬编码。不好维护。

解决思路:

  • 把SpringConfiguration类中的对象,分模块编写

  • 把数据源对象DataSource配置信息,统一配置到资源属性文件中

创建项目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NaO7arm5-1582257206304)(media/44e02483c4c866460a30629201f22080.png)]

优化方式1:编写持久层配置类

package cn.itheima.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;

/**
 * 持久层配置类
 */
public class DaoConfiguration {

   
    @Bean(value="jdbcTemplate")
    public JdbcTemplate createJdbcTemplate(DataSource dataSource){
        // 创建JdbcTemplate对象
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);

        return jdbcTemplate;
    }

 
    @Bean(name="dataSource")
    public DataSource createDataSource(){
        // 创建DataSource
        DruidDataSource dataSource = new DruidDataSource();

        // 注入属性
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://127.0.0.1:3308/spring");
        dataSource.setUsername("root");
        dataSource.setPassword("admin");

        dataSource.setInitialSize(6);
        dataSource.setMinIdle(3);
        dataSource.setMaxActive(50);
        dataSource.setMaxWait(60000);
        dataSource.setTimeBetweenEvictionRunsMillis(60000);

        return dataSource;
    }
}

建立主配置类与其它配置类关系

@Import(value={DaoConfiguration.class})

package cn.itheima.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;

/**
 * spring配置类:相当于bean.xml文件
 *
 * 注解说明:
 *      1.@Configuration:标记当前java类,是一个spring的配置类
 *      2.@ComponentScan:配置扫描包。相当于xml配置中的context:component-scan标签
 *      3.@Import:导入其它配置类
 */
@Configuration
@ComponentScan(value = {"cn.itheima"})
@Import(value={DaoConfiguration.class})
public class SpringConfiguration {

}

测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fiKZPM7f-1582257206304)(media/0244a0b8f3d685866ac72084e3ad304b.png)]

优化方式2:编写统一资源属性文件

说明:准备属性文件的时候,按照企业实际项目中的配置习惯,通常情况下会加上前缀的方式。比如jdbc.driver或者db.driver。这样能有效防止数据源默认的用户名称问题(username)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h5irCRlC-1582257206304)(media/d1c4596dc189ad695c6444527a720899.png)]

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3308/spring
jdbc.username=root
jdbc.password=admin

jdbc.initialSize=6
jdbc.minIdle=3
jdbc.maxActive=50
jdbc.maxWait=60000
jdbc.timeBetweenERM=60000

改造持久层配置类

package cn.itheima.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;

/**
 * 持久层配置类
 */
public class DaoConfiguration {

    // 定义连接数据库的成员变量
    /**
     * 使用@Value注解,进行赋值
     * 使用格式:@Value("${}")
     */
    @Value("${jdbc.driverClassName}")
    private String driverClassName;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    @Value("${jdbc.initialSize}")
    private Integer initialSize;
    @Value("${jdbc.minIdle}")
    private Integer minIdle;
    @Value("${jdbc.maxActive}")
    private Integer maxActive;
    @Value("${jdbc.maxWait}")
    private Integer maxWait;
    @Value("${jdbc.timeBetweenERM}")
    private Integer timeBetweenERM;

    /**
     *  <!--配置JdbcTemplate-->
     *<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
     *<!--注入数据源对象-->
     *<property name="dataSource" ref="dataSource"></property>
     *</bean>
     *
     * 说明:
     *   1.创建一个JdbcTemplate对象
     *   2.给该JdbcTemplate对象,注入一个数据源对象DataSource
     *   3.把该JdbcTemplate对象,以jdbcTemplate作为bean的名称,放入spring容器中
     *
     *   注解:
     *      @Bean:
     *          作用:把方法的返回值对象,放入spring容器中
     *          属性:
     *              value:给bean取一个唯一标识名称
     *              name:给bean取一个唯一标识名称
     */
    @Bean(value="jdbcTemplate")
    public JdbcTemplate createJdbcTemplate(DataSource dataSource){
        // 创建JdbcTemplate对象
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);

        return jdbcTemplate;
    }

    @Bean(name="dataSource")
    public DataSource createDataSource(){
        // 创建DataSource
        DruidDataSource dataSource = new DruidDataSource();

        // 注入属性
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);

        dataSource.setInitialSize(initialSize);
        dataSource.setMinIdle(minIdle);
        dataSource.setMaxActive(maxActive);
        dataSource.setMaxWait(maxWait);
        dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenERM);

        return dataSource;
    }
}

导入资源属性文件

@PropertySource(value={“classpath:db.properties”})

package cn.itheima.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.*;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;

/**
 * spring配置类:相当于bean.xml文件
 *
 * 注解说明:
 *      1.@Configuration:标记当前java类,是一个spring的配置类
 *      2.@ComponentScan:配置扫描包。相当于xml配置中的context:component-scan标签
 *     3.@Import:导入其它配置类
 *     4.@PropertySource:导入资源属性文件
 */
@Configuration
@ComponentScan(value = {"cn.itheima"})
@Import(value={DaoConfiguration.class})
@PropertySource(value={"classpath:db.properties"})
public class SpringConfiguration {

}

测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FasNKkPx-1582257206305)(media/9519c14bf94228314058c45155c5331b.png)]

注解说明

注解作用
@Import导入其它模块配置类
@PropertySource导入资源属性文件

关于spring 注解和xml选择的问题

注解的优势:

配置简单,维护方便(我们找到类,就相当于找到了对应的配置)。适用于内容少的,不会经常变的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WzUGlbzf-1582257206305)(media/99d599bee1306de79d26e79733c517c2.png)]

xml的优势:

修改时,不需要修改java源代码。**不涉及重新编译和部署。**内容多的,会经常改变的,比如mybatis框架中的sql语句。

企业项目中的选择:

在实际项目中,有的公司选择xml方式;有的公司选择注解的方式。因此关于注解和xml方式,都希望大家能够应用起来。

spring整合单元测试框架junit

说明:在企业项目开发中,我们会需要整合单元测试框架junit来进行功能模块的测试。接下来我们把spring与junit进行整合。

基于纯xml版本整合

创建项目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K5TjVrtd-1582257206305)(media/34e3230dd99924cd51935d63878356a6.png)]

配置pom.xml,加入依赖包

说明:spring整合单元测试框架junit。需要导入junit单元测试框架包和spring-test测试包。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZEch6lX5-1582257206305)(media/ea085f8f0e26b2688bbb00c3669fc658.png)]

<?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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.itheima</groupId>
    <artifactId>spring-day02-07case-xml-junit</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>jar</packaging>

    <properties>
        <!--spring版本-->
        <spring.version>5.0.2.RELEASE</spring.version>
        <!--druid版本-->
        <druid.version>1.0.29</druid.version>
        <!--mysql驱动版本-->
        <mysql.version>5.1.6</mysql.version>
        <!--junit 版本-->
        <junit.version>4.12</junit.version>
    </properties>

    <dependencies>
        <!--spring ioc依赖包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--spring jdbc包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--spring test包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--数据库连接池druid-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${druid.version}</version>
        </dependency>
        <!--mysql驱动包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>

        <!--junit单元测试包-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
        </dependency>

    </dependencies>
    
</project>

编写测试类

@RunWith(value = SpringJUnit4ClassRunner.class)
@ContextConfiguration(value={“classpath:bean.xml”})

package cn.itheima.test;

import cn.itheima.po.Customer;
import cn.itheima.service.CustomerService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

/**
 * spring整合junit测试
 *
 * 整合步骤:
 *     1.导入junit单元测试框架包
 *     2.导入spring提供的测试包(spring-test)
 *     3.通过@RunWith注解,把junit的测试类,替换成spring提供的测试类(SpringJUnit4ClassRunner)
 *     4.通过@ContextConfiguration注解,加载spring的配置文件
 */
@RunWith(value = SpringJUnit4ClassRunner.class)
@ContextConfiguration(value={"classpath:bean.xml"})
public class SpringJunit {

    /**
     * 版本一:测试查询全部客户列表数据
     *
     * 存在的问题:
     *      1.假如有多个测试方法,每一个测试方法中都需要手动创建spring容器,并且手动获取
     *      customerService对象。麻烦!
     *  期望:
     *      1.能不能让框架自动创建spring容器,自动给customerService赋值呢?
     */
    /*@Test
    public void findAllCustomersTest(){

        // 1.加载spring配置文件,创建spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean.xml");

        // 2.获取客户service对象
        CustomerService customerService = (CustomerService) context.getBean("customerService");

        // 3.查询全部客户列表数据
        List<Customer> list = customerService.findAllCustomers();
        for(Customer c:list){
            System.out.println(c);
        }

    }*/

    /**
     * 版本二:测试查询全部客户列表数据
     */
    @Autowired
    private CustomerService customerService ;

    @Test
    public void findAllCustomersTest2(){
        // 1.查询客户列表
        List<Customer> list = customerService.findAllCustomers();

        for(Customer c:list){
            System.out.println(c);
        }
    }
}


测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zUvu6vkU-1582257206305)(media/9920d76da4fe080186e8cbbd87f0a0ed.png)]

整合步骤小结

第一步:导入junit单元测试框架包

第二步:导入spring提供的测试包(spring-test)

第三步:通过@RunWith注解,把junit的测试类,替换成spring提供的测试类(SpringJUnit4ClassRunner)

第四步:通过@ContextConfiguration注解,加载spring配置文件

基于纯注解版本整合

创建项目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JgOPFdNp-1582257206306)(media/a663d1e57aa08cddae6613c68ce8296b.png)]

配置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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.itheima</groupId>
    <artifactId>spring-day02-08case-annotation-v1-junit</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>jar</packaging>

    <properties>
        <!--spring版本-->
        <spring.version>5.0.2.RELEASE</spring.version>
        <!--druid版本-->
        <druid.version>1.0.29</druid.version>
        <!--mysql驱动版本-->
        <mysql.version>5.1.6</mysql.version>
        <!--junit 版本-->
        <junit.version>4.12</junit.version>
    </properties>

    <dependencies>
        <!--spring ioc依赖包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--spring jdbc包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--spring test包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--数据库连接池druid-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${druid.version}</version>
        </dependency>
        <!--mysql驱动包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>

        <!--junit单元测试包-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
        </dependency>
    </dependencies>
    
</project>

编写测试类

@RunWith(value = SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class})

package cn.itheima.test;

import cn.itheima.config.SpringConfiguration;
import cn.itheima.po.Customer;
import cn.itheima.service.CustomerService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

/**
 * spring整合junit测试
 *
 * 整合步骤:
 *      1.导入junit单元测试框架包
 *      2.导入spring提供的测试包(spring-test)
 *      3.通过@RunWith注解,把junit的测试类,替换成spring提供的测试类(SpringJUnit4ClassRunner)
 *      4.通过@ContextConfiguration注解,加载spring的配置类
 */
@RunWith(value = SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunit {

    // 定义客户service
    @Autowired
    private CustomerService customerService;

    /**
     * 测试查询全部客户列表数据
     */
    @Test
    public void findAllCustomersTest(){
       // 1.查询全部客户列表数据
        List<Customer> list = customerService.findAllCustomers();
        for(Customer c:list){
            System.out.println(c);
        }
    }
}

测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hjTBkz9L-1582257206306)(media/19dc421d461e88dfbda4066ef284d19a.png)]

整合步骤小结

第一步:导入junit单元测试框架包

第二步:导入spring提供的测试包(spring-test)

第三步:通过@RunWith注解,把junit的测试类,替换成spring提供的测试类(SpringJUnit4ClassRunner)

第四步:通过@ContextConfiguration注解,加载spring配置类

小结

(1) IOC常用的xml标签

<context:property-placeholder location="sql.properties"/>       <!--加载类路径下的资源文件-->

<context:component-scan base-package="com"/>       <!-- 开启注解扫描,指定要扫描的包-->


<!--bean标签:配置javaBean对象-->
<bean id="userServerImpl" class="com.server.imp.UserServerImpl">
    <property name="userDao" ref="userDao"/>
</bean>
------------------------------------------------------------------------------------
<bean id="constructorDao" class="cn.itheima.dao.impl.ConstructorDaoImpl">
    <constructor-arg index="0" name="id" type="int" value="1" ></constructor-arg>
    <constructor-arg name="name" value="小明"></constructor-arg>
    <constructor-arg name="age" value="18"></constructor-arg>
    <constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>
<!--配置日期类型bean对象-->
<bean id="now" class="java.util.Date"></bean>
-----------------------------------------------------------------------------------
<bean id="setDao" class="cn.itheima.dao.impl.SetDaoImpl">
    <property name="id" value="1"></property>
    <property name="name" value="小花"></property>
    <property name="age" value="18"></property>
    <property name="birthday" ref="now"></property>
</bean>
<!--配置日期类型bean对象-->
<bean id="now" class="java.util.Date"></bean>
------------------------------------------------------------------------------------
<bean id="pDao" class="cn.itheima.dao.impl.SetDaoImpl"
 p:id="2" p:name="小黄" p:age="18" p:birthday-ref="now">
    
</bean>
<!--配置日期类型bean对象-->
<bean id="now" class="java.util.Date"></bean>
------------------------------------------------------------------------------------
<bean id="cDao" class="cn.itheima.dao.impl.ConstructorDaoImpl"
    c:id="3" c:name="小王" c:age="18" c:birthday-ref="now">
</bean>
</bean>
<!--配置日期类型bean对象-->
<bean id="now" class="java.util.Date"></bean>
------------------------------------------------------------------------------------
<bean id="collectionDao" class="cn.itheima.dao.impl.CollectionDaoImpl">
    <!--array-->
    <property name="array">
        <array>
            <value>array1</value>
            <value>array2</value>
        </array>
    </property>
    <!--list-->
    <property name="list">
        <list>
            <value>list1</value>
            <value>list2</value>
        </list>
    </property>
    <!--set-->
    <property name="set">
        <set>
            <value>set1</value>
            <value>set2</value>
        </set>
    </property>
    <!--map-->
    <property name="map">
        <map>
            <entry key="mapk1" value="mapv1"></entry>
            <entry key="mapk2" value="mapv2"></entry>
        </map>
    </property>
    <!--prop-->
    <property name="prop">
        <props>
            <prop key="propk1">propv1</prop>
            <prop key="propk2">propv2</prop>
        </props>
    </property>
</bean>

(2) IOC常用的注解

@Component 创建对象加入容器, 例如:工具类、其他组件

@Repository 创建对象加入容器, 例如:标识数据库访问层的组件

@Service 创建对象加入容器, 例如:标识乐屋逻辑层的组件

@Controller 创建对象加入容器 例如:标识控制层的组件

@Autowired 从容器中找对象,给属性赋值。根据类型、名称去容器中找。

@Qualifier 结合Autowired使用,可以指定按照名称去容器找对象注入。

@Value 给简单类型属性直接赋值/获取配置文件值@Value(“${key}”)

@Resource 从容器中找对象,给属性赋值。 根据名称、类型去容器中查找

@Scope 单例/多例

@PostConstruct 初始化方法,创建对象后执行

@PreDestroy 销毁先执行

@Lazy 延迟初始化

@Configuration 取代bean.xml ;

@ComponentScan 注解扫描

@Import 导入其他配置类

@Bean 在java配置类中修饰方法,自动把方法返回值放入容器

@PropertySource 加载外部配置文件

@Value 获取@ PropertySource加载的配置文件的值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值