学习目标
-
能够编写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和注解混合使用配置方式,再到完全使用注解配置方式的演化。
注解配置入门体验
创建项目
编写项目中的业务层和持久层对象
编写持久层对象
- 客户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();
}
}
测试
注解入门配置
改造客户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>
测试
常用注解分类
创建对象相关注解【掌握】
@Component
作用:
相当于bean.xml中的bean标签
属性:
value:给bean取一个唯一标识名称,相当于bean标签id属性
细节:
-
value属性可以省略
-
默认使用类的名称首字母小写,作为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.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的名称注入
细节:
-
在成员变量上不能单独使用,需要配合@Autowired注解一起使用
-
在方法形参上可以单独使用
案例代码
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,实现查询全部客户列表数据。
需求实现
纯xml版本【掌握】
创建项目
配置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);
}
}
}
xml与注解混合版本【掌握】
说明:上一个xml版本中,我们完整的实现了案例需求。接下来结合注解配置,完成xml与注解的混合使用。那么我们的思路在哪里呢?
实现思路:
-
把自定义的对象(客户service、客户dao),使用注解方式进行配置
-
把第三方提供的对象(JdbcTemplate、DataSource),使用xml方式进行配置
创建项目
改造客户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>
测试
纯注解版本【了解】
说明:在注解与xml实现案例版本中,已经将客户service和dao实现类对象使用注解进行配置。但还是保留了bean.xml文件,在bean.xml中配置了扫描包、JdbcTemplate、DataSource对象。接下来我们将bean.xml中的内容也使用注解方式配置。即纯注解的案例版本。
这里需要思考一个问题:目前创建spring的容器入口是bean.xml文件,那么纯注解版本中,创建spring的容器入口在哪儿呢?
答案是:编写一个java类,作为spring的配置类,该配置类的作用相当于bean.xml文件。
创建项目
编写配置类
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);
}
}
}
注解说明
注解 | 作用 |
---|---|
@Configuration | 标记当前java类,是spring配置类 |
@ComponentScan | 配置扫描包,相当于xml文件这的context:component-scan标签 |
@Bean | 将方法返回值对象,放入spring容器中 |
纯注解版本-优化版本【掌握】
在上一个纯注解配置的版本中,有两个方面的问题需要解决:
-
所有对象都配置到SpringConfiguration类中,内容太多,不好维护
-
数据源DataSource配置,连接数据库的四个基本要素和其它连接池信息,直接在java代码中写死了,是硬编码。不好维护。
解决思路:
-
把SpringConfiguration类中的对象,分模块编写
-
把数据源对象DataSource配置信息,统一配置到资源属性文件中
创建项目
优化方式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 {
}
测试
优化方式2:编写统一资源属性文件
说明:准备属性文件的时候,按照企业实际项目中的配置习惯,通常情况下会加上前缀的方式。比如jdbc.driver或者db.driver。这样能有效防止数据源默认的用户名称问题(username)。
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 {
}
测试
注解说明
注解 | 作用 |
---|---|
@Import | 导入其它模块配置类 |
@PropertySource | 导入资源属性文件 |
关于spring 注解和xml选择的问题
注解的优势:
配置简单,维护方便(我们找到类,就相当于找到了对应的配置)。适用于内容少的,不会经常变的
xml的优势:
修改时,不需要修改java源代码。**不涉及重新编译和部署。**内容多的,会经常改变的,比如mybatis框架中的sql语句。
企业项目中的选择:
在实际项目中,有的公司选择xml方式;有的公司选择注解的方式。因此关于注解和xml方式,都希望大家能够应用起来。
spring整合单元测试框架junit
说明:在企业项目开发中,我们会需要整合单元测试框架junit来进行功能模块的测试。接下来我们把spring与junit进行整合。
基于纯xml版本整合
创建项目
配置pom.xml,加入依赖包
说明:spring整合单元测试框架junit。需要导入junit单元测试框架包和spring-test测试包。
<?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);
}
}
}
测试
整合步骤小结
第一步:导入junit单元测试框架包
第二步:导入spring提供的测试包(spring-test)
第三步:通过@RunWith注解,把junit的测试类,替换成spring提供的测试类(SpringJUnit4ClassRunner)
第四步:通过@ContextConfiguration注解,加载spring配置文件
基于纯注解版本整合
创建项目
配置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);
}
}
}
测试
整合步骤小结
第一步:导入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加载的配置文件的值