spring框架的入门练习和简介

本文介绍了Spring框架的核心概念——控制反转(IOC),并详细讲述了如何进行基于XML和注解的配置,包括环境搭建、对象的创建与管理、依赖注入等。通过案例展示了Spring在业务层和持久层的解耦,以及与JUnit的整合,提供了测试环境的搭建和测试类的配置。文章强调了注解配置的便利性和灵活性,并对比了XML配置的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring第一天

  1. Spring概述

1.1程序的耦合和解耦

      1.  什么是程序的耦合

我们在开发中,会写很多的类,而有些类之间不可避免的产生依赖关系,这种依赖关系称之为耦合。有些依赖关系是必须的,有些依赖关系可以通过优化代码来解除的。请看下面的示例代码:

/**

* 客户的业务层实现类依赖customerDao类,这两个类就称为耦合

*/

public class CustomerServiceImpl implements ICustomerService {

private ICustomerDao customerDao = new CustomerDaoImpl();

}

上面的代码表示:业务层调用持久层,并且此时业务层在依赖持久层的接口和实现类。如果此时没有持久层实现类,编译将不能通过。这种依赖关系就是我们可以通过优化代码解决的。

再比如:

下面的代码中,我们的类依赖了 MySQL 的具体驱动类,如果这时候更换了数据库品牌,我们需要改源码来修改数据库驱动。这显然不是我们想要的。

public class JdbcDemo1 {

/**

* JDBC 操作数据库的基本入门中存在什么问题?

* 导致驱动注册两次是个问题,但不是严重的。

* 严重的问题:是当前类和 mysql 的驱动类有很强的依赖关系。

* 当我们没有驱动类的时候,连编译都不让。

* 那这种依赖关系,就叫做程序的耦合

*

* 我们在开发中,理想的状态应该是:

* 我们应该尽力达到的:编译时不依赖,运行时才依赖。

*/

public static void main(String[] args) throws Exception {

//1.注册驱动

//DriverManager.registerDriver(new com.mysql.jdbc.Driver());

Class.forName("com.mysql.jdbc.Driver");

//2.获取连接

//3.获取预处理 sql 语句对象

//4.获取结果集

//5.遍历结果集

}

      1.  解决程序耦合的思路

当是我们讲解 jdbc 时,是通过反射来注册驱动的,代码如下:

Class.forName("com.mysql.jdbc.Driver");

这时的好处是,我们的类中不再依赖具体的驱动类,此时就算删除 mysql 的驱动 jar 包,依然可以编译。但是因为没有驱动类,所以不能运行。

不过,此处也有个问题,就是我们反射类对象的全限定类名字符串是在 java 类中写死的,一旦要改还是要修改源码。

解决这个问题也很简单,使用配置文件配置。

      1. 工厂模式解耦

在实际开发中我们可以把所有的 dao mapper 和 service 和 action web controller对象使用配置文件配置起来,当启动服务器应用加载的时候,通过读取配置文件,把这些对象创建出来 并存起来。在接下来的使用的时候,直接拿过来用就好了。

1.1.4 控制反转-Inversion Of Control

1 、存哪去?

分析:由于我们是很多对象,肯定要找个集合来存。这时候有 Map 和 List 供选择。

到底选 Map 还是 List 就看我们有没有查找需求。有查找需求,选 Map。

所以我们的答案就是

在应用加载时,创建一个 Map,用于存放 action,Service 和 dao 对象。

我们把这个 map 称之为 容器。

2、还是没解释什么是工厂?

工厂就是负责给我们从容器中获取指定对象的类。这时候我们获取对象的方式发生了改变。

原来:

我们在获取对象时,都是采用 new 的方式。是主动的。

现在:

我们获取对象时,同时跟工厂要,有工厂为我们查找或者创建对象。是被动的。

这种被动接收的方式获取对象的思想就是控制反转,它是 spring 框架的核心之一。

它的作用只有一个:削减计算机程序的耦合。

    1.  Spring介绍
      1. Spring 概述

Spring框架有两大核心 分别是IOC(控制反转)和AOP(面向切面编程)

1.2.1.1 Spring简介

Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源框架,以 IoCInverse Of Control

反转控制)和 AOPAspect Oriented Programming:面向切面编程)为内核,提供了展现层 SpringMVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的 Java EE 企业应用开源框架。

1.2.1.2 Spring的发展历程

1997 年 IBM 提出了 EJB 的思想

1998 年,SUN 制定开发标准规范 EJB1.0

1999 年,EJB1.1 发布

2001 年,EJB2.0 发布

2003 年,EJB2.1 发布

2006 年,EJB3.0 发布

Rod Johnson spring  之父)

Expert One-to-One J2EE Design and Development(2002)

阐述了 J2EE 使用 EJB 开发设计的优点及解决方案

Expert One-to-One J2EE Development without EJB(2004)

阐述了 J2EE 开发不使用 EJB 的解决方式(Spring 雏形)

      1.  Spring的优势

方便解耦,简化开发

通过 Spring 提供的 IoC 容器,可以将对象间的依赖关系交由 Spring 进行控制,避免硬编码所造成的过度程序耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。

AOP  编程的支持

通过 Spring 的 AOP 功能,方便进行面向切面的编程,许多不容易用传统 OOP 实现的功能可以通过 AOP 轻松应付。

声明式事务的支持

可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务的管理,提高开发效率和质量。

方便程序的测试

可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。

方便集成各种优秀框架

Spring 可以降低各种框架的使用难度,提供了对各种优秀框架(Struts、Hibernate、Hessian、Quartz 任务调度框架  等)的直接支持。低 降低 JavaEE API  的使用难度Spring 对 JavaEE API(如 JDBC、JavaMail、远程调用  CXF 等)进行了薄薄的封装层,使这些 API 的使用难度大为降低。

Java  源码是经典学习范例

Spring 的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对 Java 设计模式灵活运用以及对 Java 技术的高深造诣。它的源代码无意是 Java 技术的最佳实践的范例。

 

 

 

      1.  Spring的体系结构

 

      1.  Spring开发包

官网:http://spring.io/

下载地址:

http://repo.springsource.org/libs-release-local/org/springframework/spring

解压:(Spring 目录结构:)

* docs  :API 和开发规范.

* libs  :jar 包和源码.

* schema :约束.

我们上课使用的版本是Spring 4.2.4

  1. 使用Spring的IOC解决程序耦合

2.1案例的前期准备

本章我们使用的案例是,客户的业务层和持久层的依赖关系解决。在开始 spring 的配置之前,我们要先准备一下环境。由于我们是使用 spring 解决依赖关系,并不是真正的要做增删改查操作,所以此时我们没必要写实体类。并且我们在此处使用的是 java 工程,不是 java web 工程。

2.1.1 创建业务层接口和实现类

客户接口: CustomerService

 

/**

* 客户的业务层接口

*/

public interface ICustomerService {

/**

* 保存客户

* @param customer

*/

void saveCustomer();

}

 

客户的实现类 CustomerServiceImpl:

/**

* 客户的业务层实现类

*/

public class CustomerServiceImpl implements ICustomerService {

private ICustomerDao customerDao = new CustomerDaoImpl();// 此处有依赖关系

@Override

public void saveCustomer() {

customerDao.saveCustomer();

}

}

 

2.1.2  创建持久层接口和实现类

客户的持久层接口:

public interface ICustomerDao {

/**

* 保存客户

*/

void saveCustomer();

}

 

 

 客户的持久层实现类:

 

public class CustomerDaoImpl implements ICustomerDao {

@Override

public void saveCustomer() {

System.out.println("保存了客户");

}

}

 

 

2.2 基于XML的配置

2.2.1 环境搭建

2.2.1.1 第一步: 拷贝必备的jar包到工程的lib目录

2.2.1.2 第二步:在类的根路径下创建一个任意名称的 xml  文件 (不能是中文)

给配置文件导入约束:

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

<!-- 导入 schema

约束的位置在:

..\spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html

文件中。注意:要导入 schema 约束

-->

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

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

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

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

</beans>

2.2.1.3  第三步:把资源交给 spring  来管理置 ,在配置文件中配置 service  和 dao

<!-- 把资源交给 spring 来管理 -->

<bean id="customerDao" class="com.bdqn.dao.impl.CustomerDaoImpl"/>

<bean id="customerService" class="com.bdqn.service.impl.CustomerServiceImpl"/>

2.2.2  测试环境是否成功

2.2.2.1  获取 spring  容器

/**

* 模拟一个表现层

*/

public class Client {

/**

* 获取 spring 的容器,以及从容器中获取 bean 对象

*

* ApplicationContext

* 它是一个接口,有两个实现类。

* 分别是:

* ClassPathXmlApplicationContext:

* 它永远都是从类的根路径下加载配置文件 推荐使用这种

* FileSystemXmlApplicationContext:

* 它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。

*/

public static void main(String[] args) {

//1.使用 ApplicationContext 接口,就是在获取 spring 容器

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

//2.根据 bean 的 id 获取对象

ICustomerService  customerService  =  (ICustomerService)

ac.getBean("customerService");

System.out.println(customerService);

ICustomerDao customerDao = (ICustomerDao) ac.getBean("customerDao");

System.out.println(customerDao);

}

}

问题:由于对象都交给 spring 管理了,这时如果我们把 service 实现了的这行代码:

private ICustomerDao customerDao = new CustomerDaoImpl();// 此处有依赖关系

改为

private ICustomerDao customerDao = null;

使用 service 对象调用 saveCustomer 方法会出现什么问题呢?

运行结果:

空指针异常。

原因是 customerDao 对象没有赋值。

如果在程序运行期间,spring  框架能帮我们给 customerDao  对象赋了值,那该多好。

带着脑海里的这个想法,继续往下看。

2.2.2.2 Spring工厂类结构

BeanFactory 才是 Spring 容器中的顶层接口。ApplicationContext 是它的子接口。

BeanFactory 和 ApplicationContext 的区别:创建对象的时间点不一样。

ApplicationContext:只要一读取配置文件,默认情况下就会创建对象。

BeanFactory:什么时候对象使用什么时候创建对象。

2.2.3 IOC 中 中 bean  标签 和 管理对象细节

2.2.3.1 bean  标签

作用:

用于配置对象让 spring 来创建的。

默认情况下它调用的是类中的无参构造函数。如果没有无参构造函数则不能创建成功。

属性:

id :给对象在容器中提供一个唯一标识。用于获取对象。

class :指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。

scope :指定对象的作用范围。

* singleton :默认值,单例的.

* prototype :多例的.

* request  :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中.

* session  :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中.

init-method :指定类中的初始化方法名称。

destroy-method :指定类中销毁方法名称。

2.2.3.2 bean  的作用范围和生命周期

单例对象: scope="singleton"

一个应用只有一个对象的实例。它的作用范围就是整个引用。

生命周期:

对象出生:当应用加载,创建容器时,对象就被创建了。

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

对象死亡:当应用卸载,销毁容器时,对象就被销毁了。

多例对象: scope="prototype"

每次访问对象时,都会重新创建对象实例。

生命周期:

对象出生:当使用对象时,创建新的对象实例。

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

对象死亡:当对象长时间不用时,被 java 的垃圾回收器回收了。

2.2.4 spring  的依赖注入

2.2.4.1  依赖注入的概念

它是 spring 框架核心 ioc 的具体实现方式。简单的说,就是坐等框架把对象传入,而不用我们自己去获取.

2.2.4.2 构造函数注入

顾名思义,就是使用类中的构造函数,给成员变量赋值。注意,赋值的操作不是我们自己做的,而是通过配置的方式,让 spring 框架来为我们注入。具体代码如下:

public class CustomerServiceImpl implements ICustomerService {

private String name;

private Integer age;

private Date birthday;

public CustomerServiceImpl(String name, Integer age, Date birthday) {

this.name = name;

this.age = age;

this.birthday = birthday;

}

@Override

public void saveCustomer() {

System.out.println(name+","+age+","+birthday);

}

}

<!-- 使用构造函数的方式,给 service 中的属性传值

要求:

类中需要提供一个对应参数列表的构造函数。

涉及的标签:

constructor-arg

属性:

index:指定参数在构造函数参数列表的索引位置

type:指定参数在构造函数中的数据类型

name:指定参数在构造函数中的名称 用这个找给谁赋值

=======上面三个都是找给谁赋值,下面两个指的是赋什么值的==============

value:它能赋的值是基本数据类型和 String 类型

ref:它能赋的值是其他 bean 类型,也就是说,必须得是在配置文件中配置过的 bean

-->

<bean id="customerService" class="com.bdqn.service.impl.CustomerServiceImpl">

<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 id="now" class="java.util.Date"></bean>

 

2.2.4.3 Set方法注入(重点)

顾名思义,就是在类中提供需要注入成员的 set 方法。具体代码如下:

public class CustomerServiceImpl implements ICustomerService {

private String name;

private Integer age;

private Date birthday;

public void setName(String name) {

this.name = name;

}

public void setAge(Integer age) {

this.age = age;

}

public void setBirthday(Date birthday) {

this.birthday = birthday;

}

@Override

public void saveCustomer() {

System.out.println(name+","+age+","+birthday);

}

}

<!-- 通过配置文件给 bean 中的属性传值:使用 set 方法的方式

涉及的标签:

property

属性:

name:找的是类中 set 方法后面的部分

ref:给属性赋值是其他 bean 类型的

value:给属性赋值是基本数据类型和 string 类型的

实际开发中,此种方式用的较多。

-->

<bean id="customerService" class="com.bdqn.service.impl.CustomerServiceImpl">

<property name="name" value="test"></property>

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

<property name="birthday" ref="now"></property>

</bean>

<bean id="now" class="java.util.Date"></bean>

2.2.4.4  注入集合属性

顾名思义,就是给类中的集合成员传值,它用的也是 set 方法注入的方式,只不过变量的数据类型都是集合。我们这里介绍注入数组,List,Set,Map,Properties。具体代码如下:

public class CustomerServiceImpl implements ICustomerService {

private String[] myStrs;

private List<String> myList;

private Set<String> mySet;

private Map<String,String> myMap;

private Properties myProps;

public void setMyStrs(String[] myStrs) {

this.myStrs = myStrs;

}

public void setMyList(List<String> myList) {

this.myList = myList;

}

public void setMySet(Set<String> mySet) {

this.mySet = mySet;

}

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

this.myMap = myMap;

}

public void setMyProps(Properties myProps) {

this.myProps = myProps;

}

@Override

public void saveCustomer() {

System.out.println(Arrays.toString(myStrs));

System.out.println(myList);

System.out.println(mySet);

System.out.println(myMap);

System.out.println(myProps);

}

}

<!-- 注入集合数据

List 结构的:

array,list,set

Map 结构的

map,entry,props,prop

-->

<bean id="customerService" class="com.bdqn.service.impl.CustomerServiceImpl">

<!-- 在注入集合数据时,只要结构相同,标签可以互换 -->

<!-- 给数组注入数据 -->

<property name="myStrs">

<set>

<value>AAA</value>

<value>BBB</value>

<value>CCC</value>

</set>

</property>

<!-- 注入 list 集合数据 -->

<property name="myList">

<array>

<value>AAA</value>

<value>BBB</value>

<value>CCC</value>

</array>

</property>

<!-- 注入 set 集合数据 -->

<property name="mySet">

<list>

<value>AAA</value>

<value>BBB</value>

<value>CCC</value>

</list>

</property>

<!-- 注入 Map 数据 -->

<property name="myMap">

<props>

<prop key="testA">aaa</prop>

<prop key="testB">bbb</prop>

</props>

</property>

<!-- 注入 properties 数据 -->

<property name="myProps">

<map>

<entry key="testA" value="aaa"></entry>

<entry key="testB">

<value>bbb</value>

</entry>

</map>

</property>

</bean>

第3 章 附录

3.1  Spring  配置文件中提示的配置

3.1.1 复制路径:

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

3.1.2 查找 XML Catalog:

 

 

 

 

Spring  第 二 天

第1 章 基于注解的 IOC  配置

1.1  写在最前

学习基于注解的 IoC 配置,大家脑海里首先得有一个认知,即注解配置和 xml 配置要实现的功能都是一样的,都是要降低程序间的耦合。只是配置的形式不一样。关于实际的开发中到底使用 xml 还是注解,每家公司有着不同的使用习惯。所以这两种配置方式我们都需要掌握。

1.2  环境搭建

1.2.1  第一步:拷贝必备 jar 包到工程的 lib 目录。

注意:在基于注解的配置中,我们还要多拷贝一个 aop 的 jar 包。如下图:

1.2.2  第二步:在类的根路径下创建一个任意名称的 xml  文件 (不能是中文)

基于注解整合时,导入约束时需要多导入一个 context 名称空间下的约束.

 

给配置文件导入 context 约束:

 

 

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

<?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/beans/spring-context.xsd">

  

</beans>

 

1.2.3 使用@Component 注解配置管理的资源

@Component(value="customerServie")

public class CustomerServiceImpl implements CustomerService {

   @Override

   public void saveCustomer(Customer customer) {

      System.out.println("执行了保存客户!");

   }

}

1.2.4  第四步在 spring  的配置文件中开启 spring  对注解 ioc 的支持

<!-- 告知spring框架在,读取配置文件,创建容器时,扫描注解,依据注解创建对象,并存入容器中 -->

<context:component-scan base-package="com.bdqn"></context:component-scan>

1.3 常用注解

1.3.1  用于创建对象的

相当于:<bean id="" class="">

1.3.1.1 @Component

作用:

把资源让 spring 来管理。相当于在 xml 中配置一个 bean。

属性:

value:指定 bean 的 id。如果不指定 value 属性,默认 bean 的 id 是当前类的类名。首

字母小写。

1.3.1.2 @Controller @Service @Repository

他们三个注解都是针对一个的衍生注解,他们的作用及属性都是一模一样的。

他们只不过是提供了更加明确的语义化。

@Controller :一般用于表现层的注解。

@Service :一般用于业务层的注解。

@Repository :一般用于持久层的注解。

细节:如果注解中有且只有一个属性 要赋值时是 ,且名称是 value ,value可以省略 。

1.3.2  用于注入数据的

相当于:<property name="" ref=""> <property name="" value="">

1.3.2.1 @Autowired

作用:

自动按照类型注入。当使用注解注入属性时,set 方法可以省略。它只能注入其他 bean

类型。当有多个类型匹配时,使用要注入的对象变量名称作为 bean 的 id,在 spring 容器查找,找到了也可以注入成功。找不到就报错。

1.3.2.2 @Qualifier(不经常使用)

作用:

在自动按照类型注入的基础之上,再按照 Bean 的 id 注入。它在给字段注入时不能独

立使用,必须和@Autowire 一起使用;但是给方法参数注入时,可以独立使用。

属性:

value:指定 bean 的 id。

1.3.2.3 @Resource

作用:

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

属性:

name:指定 bean 的 id。

1.3.2.4 @Value

作用:

注入基本数据类型和 String 类型数据的

属性:

value:用于指定值

1.3.3  用于改变作用范围的:

相当于:<bean id="" class="" scope="">

1.3.3.1 @Scope

作用:

指定 bean 的作用范围。

属性:value:指定范围的值。

取值:singleton prototype request session

1.3.4  和生命周期相关的:( 了解)

相当于:<bean id="" class="" init-method="" destroy-method="" />

1.3.4.1 @PostConstruct

作用:

用于指定初始化方法。

1.3.4.2 @PreDestroy

作用:

用于指定销毁方法。

1.3.5  关于注解和 XML  的选择问题

注解的优势:

配置简单,维护方便(我们找到类,就相当于找到了对应的配置)。

XML  的优势:

修改时,不用改源码。不涉及重新编译和部署

1.4  spring  管理对象细节

基于注解的 spring IoC 配置中,bean 对象的特点和基于 XML 配置是一模一样的。

写到此处,基于注解的 IoC 配置已经完成,但是大家都发现了一个问题:我们依然离不开 spring的 xml 配置文件,那么能不能不写这个 bean.xml,所有配置都用注解来实现呢?

答案是肯定的,请看下一章节。

1.5  spring  的纯注解配置

1.5.1  待改造的问题

我们发现,之所以我们现在离不开 xml 配置文件,是因为我们有一句很关键的配置:

<!-- 告知spring框架在,读取配置文件,创建容器时,扫描注解,依据注解创建对象,并存入容器中 -->

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

如果他要也能用注解配置,那么我们就可以脱离 xml 文件了。

1.5.2 使用注解配置要扫描的包

项目结构图:

在此图中,我们已经一点也看不到 xml 的身影了。那么,那句关键的配置跑哪去了呢?

在一个新的类上:用这个类代替配置文件.

配置类代码:

@Configuration //标明该类是一个配置类

@ComponentScan(basePackages= {"com.bdqn"})//配置扫描的包

public class SpringConfiguration {

}

测试类代码:

@Test

   public void testConfig() {

//1.获取容器:由于我们已经没有了 xml 文件,所以再用读取 xml 方式就不能用了。

//这时需要指定加载哪个类上的注解

      ApplicationContext aContext=new AnnotationConfigApplicationContext(SpringConfiguration.class);

      //从容器中获得对象

      CustomerService customerService = (CustomerService) aContext.getBean("customerServie");

      Customer customer=new Customer();

      customer.setCustName("李斯");

      customer.setCustSource("互联网");

      //调用对象的保存用户的方法

      customerService.saveCustomer(customer);

   }

 

1.5.3  新注解说明

1.5.3.1 @Configuration

作用:

用于指定当前类是一个配置类,会从该类上加载注解。读取该类上@ ComponentScan 注解

初始化 spring 容器。

1.5.3.2 @ComponentScan

作用:

用于指定 spring 在初始化容器时要扫描的包。

属性:

basePackages :用于指定要扫描的包。和该注解中的 value 属性作用一样。

1.5.3.3 @Bean

作用:把方法的返回值放入到Spring容器中

该注解只能写在方法上,表明使用此方法创建一个对象,并且交给 spring 管理。

属性:name :给当前@Bean 注解的方法创建的对象指定一个名称(即 bean 的 id)。

配置类代码:

@Component

public class JdbcConfig {

   /**

   把方法的返回值放入Spring容器  name属性用于指定对象的名字 

   相当于 <bean id="ds" class="com.mchange.v2.c3p0.ComboPooledDataSource"></bean>

   */

   @Bean(name="ds")

   public DataSource getDs() throws Exception {

      //创建一个数据源

      ComboPooledDataSource dataSource=new ComboPooledDataSource();

      //设置数据源连接数据库的四要素

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

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

      dataSource.setUser("root");

      dataSource.setPassword("root");

      //返回数据源

      return dataSource;

   }

}

测试代码:

@Test

   public void testBean() {

      //根据配置类获得容器

      ApplicationContext aContext=new AnnotationConfigApplicationContext(SpringConfiguration.class);

      //从容器中获得数据源

      DataSource dSource=(DataSource) aContext.getBean("ds");

      //创建QueryRunner对象

      QueryRunner runner=new QueryRunner(dSource);

      //实行插入数据语句

      try {

         runner.update("insert into account (username,money) values('Monica',500000)");

      } catch (SQLException e) {

         e.printStackTrace();

      }

   }

1.5.3.4 @Import

作用:

用于导入其他配置类

属性:

value[] :用于指定其他配置类的字节码。

示例代码:这样就不需要再向容器中放入JdbcConfig类,@Component注解省略

直接使用@Important注解加载配置类

@Configuration //标明该类是一个配置类

@ComponentScan("com.bdqn")//配置扫描的包

@Import(JdbcConfig.class)//用于导入其它配置类

public class SpringConfiguration {

}

1.5.3.5 @PropertySource

作用:用于加载.properties 文件中的配置

属性:

value[] :用于指定 properties 文件位置。如果是在类路径下,需要写上 classpath:

public class JdbcConfig {

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

   private String driver;

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

   private String url;

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

   private String username;

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

   private String password;

   @Bean(name="ds")

   public DataSource getDs() throws Exception {

      //创建一个数据源

      ComboPooledDataSource dataSource=new ComboPooledDataSource();

      //设置数据源连接数据库的四要素

      dataSource.setDriverClass(driver);

      dataSource.setJdbcUrl(url);

      dataSource.setUser(username);

      dataSource.setPassword(password);

      //返回数据源

      return dataSource;

   }

注意4.3以前版本需要提供占位符类:

我们目前上课使用的版本是 4.2.4, spring4.3  以前都需要提供一个占位符配置器:

PropertySourcesPlaceholderConfigurer

而在 spring4.3  以后,则不需要提供。

提供 的方式如下:(在 SpringConfiguration JdbcConfig 配置均可

4.2版本的配置

@Configuration //标明该类是一个配置类

@ComponentScan("com.bdqn")//配置扫描的包

@Import(JdbcConfig.class)//用于导入其它配置类

@PropertySource("classpath:/com/bdqn/config/jdbc.properties")

//导入properties配置文件 value属性用于指定配置文件的位置

public class SpringConfiguration {

   @Bean(name="pspc")

   public static PropertySourcesPlaceholderConfigurer createPSPC() {

      return new PropertySourcesPlaceholderConfigurer();

   }

}

 

1.5.3.6 @Qualifier的第二种使用方法

1.第一种方式  和@Autowire一起配合起来使用,用于指定固定一个对象的配置.

2.用于向方法参数注入Spring容器中对象.

示例代码:

@Bean(name="ds")

   public DataSource getDs() throws Exception {

      //创建一个数据源

      ComboPooledDataSource dataSource=new ComboPooledDataSource();

      //设置数据源连接数据库的四要素

      dataSource.setDriverClass(driver);

      dataSource.setJdbcUrl(url);

      dataSource.setUser(username);

      dataSource.setPassword(password);

      //返回数据源

      return dataSource;

   }

   /**

    * @Qualifier("ds") 直接使用容器中的ds 向形参赋值

    */

   @Bean(name="qr")

   public QueryRunner getRunner(@Qualifier("ds")DataSource ds) {

      return new QueryRunner(ds);

   }

测试代码:

   @Test

   public void testBean() {

      //根据配置类获得容器

      ApplicationContext aContext=new AnnotationConfigApplicationContext(SpringConfiguration.class);

      //创建QueryRunner对象

      QueryRunner runner=(QueryRunner) aContext.getBean("qr");

      //实行插入数据语句

      try {

         runner.update("insert into account (username,money) values('runner',100)");

      } catch (SQLException e) {

         e.printStackTrace();

      }

   }

第2章Spring整合Junit

2.1  准备测试环境

2.1.1 创建业务层接口和实现类

业务层接口:

public interface CustomerService {

   //保存用户的方法

   public void saveCustomer(Customer customer);

   //查询所有用户方法

   public List<Customer> getCustomers();

}

业务层实现类:

@Component("customerServie")

public class CustomerServiceImpl implements CustomerService {

   private CustomerDao customerDao;

   //提供set方法用于注入customerDao对象

   @Override

   public void saveCustomer(Customer customer) {

      customerDao.saveCustomer(customer);

   }

   public void setCustomerDao(CustomerDao customerDao) {

      this.customerDao = customerDao;

   }

   @Override

   public List<Customer> getCustomers() {

      return customerDao.getCustomers();

   }

}

 

2.1.2 创建持久层接口和实现类

持久层接口:

public interface CustomerDao {

   //保存用户的方法

   public void saveCustomer(Customer customer);

   //查询所有用户方法

   public List<Customer> getCustomers();

}

 

持久层实现类:

@Repository

public class CustomerDaoImpl implements CustomerDao {

   @Override

   public void saveCustomer(Customer customer) {

      System.out.println("保存了用户1111:"+customer);

   }

   @Override

   public List<Customer> getCustomers() {

      System.out.println("查询所用的客户!");

      return null;

   }

}

 

2.1.3  导入 junit 的 的 jar

2.1.4 编写测试类

public class CustomrServiceTest {

   //创建CustomerService

   private CustomerService customerService;

   @Test

   public void saveCustomer() {

      Customer customer=new Customer();

      customer.setCustName("阳江");

      customer.setCustSource("旅游海滨");

      customerService.saveCustomer(customer);

   }

   @Test

   public void findAllCustomer() {

      customerService.getCustomers();

   }

}

2.2  使用 xml  配置步骤

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

   <bean id="service" class="com.bdqn.service.impl.CustomerServiceImpl">

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

   </bean>

   <bean id="dao" class="com.bdqn.dao.impl.CustomerDaoImpl"></bean>

</beans>

2.2.2  第一步:拷贝整合 junit  的必备 jar  包到 lib

此处需要注意的是,导入 jar 包时,需要导入一个 spring aop jar

2.2.3  第二步:使用@RunWith注解替换原有运行器(junit运行器)

//使用RunWith注解替换Spring的运行器

@RunWith(SpringJUnit4ClassRunner.class)

public class CustomrServiceTest {

   //创建CustomerService

   private CustomerService customerService;

   @Test

   public void saveCustomer() {

      Customer customer=new Customer();

      customer.setCustName("阳江");

      customer.setCustSource("旅游海滨");

      customerService.saveCustomer(customer);

   }

   @Test

   public void findAllCustomer() {

      customerService.getCustomers();

   }

}

 

2.2.4 第三步:使用@ContextConfiguration  指定 spring  配置文件的位置

//使用RunWith注解替换Spring的运行器

@RunWith(SpringJUnit4ClassRunner.class)

// @ContextConfiguration 用于指定配置文件的位置

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

public class CustomrServiceTest {

   //创建CustomerService

   private CustomerService customerService;

   @Test

   public void saveCustomer() {

      Customer customer=new Customer();

      customer.setCustName("阳江");

      customer.setCustSource("旅游海滨");

      customerService.saveCustomer(customer);

   }

   @Test

   public void findAllCustomer() {

      customerService.getCustomers();

   }

}

 

2.2.5  第四步使用@Autowired 给测试类中的变量注入数据

//使用RunWith注解替换Spring的运行器

@RunWith(SpringJUnit4ClassRunner.class)

// @ContextConfiguration 用于指定配置文件的位置

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

public class CustomrServiceTest {

   //创建CustomerService

   @Autowired

   private CustomerService customerService;

   @Test

   public void saveCustomer() {

      Customer customer=new Customer();

      customer.setCustName("阳江");

      customer.setCustSource("旅游海滨");

      customerService.saveCustomer(customer);

   }

   @Test

   public void findAllCustomer() {

      customerService.getCustomers();

   }

}

2.3  使用纯注解配置步骤

2.3.1  第一步:拷贝整合 junit的必备 jar 包到 lib  目录

此处需要注意的是,导入 jar 包时,需要导入一个 spring 中 aop 的 jar 包。

 

2.3.2  第二步 把资源都用注解管理

2.3.3  第三步:使用注解配置方式创建 spring

2.3.4 第四步:使用 RunWith 注解和 ContextConfiguration  注解配置

最终代码:

@Configuration

@ComponentScan("com.bdqn")

//使用RunWith注解替换Spring的运行器

@RunWith(SpringJUnit4ClassRunner.class)

// @ContextConfiguration 用于指定配置文件的位置

@ContextConfiguration(classes=CustomrServiceTest.class)

public class CustomrServiceTest {

   //创建CustomerService

   @Autowired

   private CustomerService customerService;

   @Test

   public void saveCustomer() {

      Customer customer=new Customer();

      customer.setCustName("阳江");

      customer.setCustSource("旅游海滨");

      customerService.saveCustomer(customer);

   }

   @Test

   public void findAllCustomer() {

      customerService.getCustomers();

   }

}

2.4  为什么 不把测试类配到 xml 

在解释这个问题之前,先解除大家的疑虑,配到 XML 中能不能用呢?

答案是肯定的,没问题,可以使用。

那么为什么不采用配置到 xml 中的方式呢?

这个原因是这样的:

第一:当我们在 xml 中配置了一个 bean,spring 加载配置文件创建容器时,就会创建对象。

第二:测试类只是我们在测试功能时使用,而在项目中它并不参与程序逻辑,也不会解决需求上的问题,所以创建完了,并没有使用。那么存在容器中就会造成资源的浪费。

所以,基于以上两点,我们不应该把测试配置到 xml 文件中。

总结:

今天的注解:

 

创建对象的注解:

@Component

@Controller(用于web层)

@Service(用于service)

@Repository(用于dao)

 主配置文件包扫描:

 <context:component-scan base-package="com.bdqn"></context:component-scan>

作用范围:

@Scope : singleton、prototype

 

依赖注入:

@Autowired(自动按照类型注入)

@Qualifier(和@Autowired配合使用用于指定具体类型 value属性指定)

@Resource:jdk    name属性 用于指定具体类型

如果只有一个实现类: autowire和resource注解可以互换

@Value

 

新注解:

@Configuration

@ComponentScan

@Bean       name属性 

@Import

@PropertySource

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值