一 概述
1 介绍
Spring框架是一个开源的Java EE应用程序框架,旨在简化Java企业级应用的开发难度和开发周期,主要通过控制反转(IoC)和面向切面编程(AOP)等技术实现。
容器(Container):(主要是指IoC容器)是Spring框架的核心技术,主要作用是管理对象的创建及属性的赋值,以及单例对象的销毁回收(管理对象的生命周期)。通过控制反转(IoC)技术,Spring容器负责管理对象之间的依赖关系,降低了程序的耦合度。也就是装对象的的对象,如 Tomcat 就是 Servlet 的容器。在典型的IoC场景中,容器创建了所有对象,并设置必要的属性将它们连接在一起,决定什么时间调用方法。
2 作用
Spring 提供了 JavaEE 每一层的解决方案。根据职责的划分为:控制层、业务层、持久层,使用不同框架解决不同领域的问题。
3 优势
① 方便解耦,简化开发:通过IoC容器,Spring可以管理对象间的依赖关系,避免硬编码造成的过度程序耦合。
② AOP编程的支持:Spring提供面向切面编程,可以方便地实现对程序进行权限拦截、运行监控等功能。
③ 声明式事务的支持:只需要通过配置就可以完成对事务的管理,而无需手动编程。
④ 方便程序的测试:Spring对Junit4支持,可以通过注解方便地测试Spring程序。
4 Spring FrameWork 体系
Spring Framework提供了一个简易的开发方式,这种开发方式,将避免那些可能致使底层代码变得繁杂混乱的大量的属性文件和帮助类。关键特性包括强大的基于JavaBeans的采用控制反转(Inversion of Control,IoC)原则的配置管理,使得应用程序的组建更加快捷简易。
Spring Framework总共有十几个组件,其中核心组件只有三个:Core、Context和Beans。每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:
① Core(核心容器IOC):提供Spring框架的基本功能,包含有 Beans、Core、Context 和 SpEL 模块。核心容器的主要组件是BeanFactory,它是工厂模式的实现。BeanFactory使用控制反转(IOC)模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
② Context(上下文):Spring上下文是一个配置文件,向Spring框架提供上下文信息。所以,可以很容易地使Spring框架管理的任何对象支持AOP。
③ AOP:Spring框架的面向切面编程模块,用于处理跨多个模块的横切关注点,例如日志和事务管理。
④ DAO:提供了一个统一的异常层次结构,以简化数据库访问异常的处理。
⑤ Data Access Integration:提供了集成各种ORM框架(如Hibernate和JDBC)的工具。
⑥ Web:提供了用于构建Web应用程序的工具,包括支持视图技术如JSP和Tiles,以及支持RESTful Web服务的框架。
⑦ MVC:Spring框架的模型-视图-控制器(MVC)实现,用于构建Web应用程序。
⑧ Test:提供了用于单元测试和集成测试的工具。
5 Spring 依赖
官网与版本选择
二 IoC与DI
1 IoC – 控制反转
在Spring框架中,IoC(Inversion of Control)是一个核心概念,其含义是将对象的设计和创建控制权交给一个外部容器(即IoC容器),而不是由对象本身直接控制。
这种控制反转的设计原则有助于降低代码之间的耦合度,提高组件的灵活性和可维护性。IoC容器的功能是负责管理对象的生命周期,通过依赖注入的方式装配对象,配置对象,并且管理这些对象的整个生命周期。
2 DI – 依赖注入
DI的实现主要依赖于IoC容器。它允许容器在运行期间动态地将依赖关系注入到组件中,从而降低了代码之间的耦合度。IoC容器负责创建、配置和管理应用程序中的对象及其依赖关系。当一个对象被创建时,IoC容器可以自动将该对象所依赖的其他对象注入给它。这个过程可以在运行时动态地发生,使得应用程序的组件之间的耦合度大大降低。
在Spring中,依赖注入通常通过以下几种方式实现:
① 构造函数注入:通过类的构造函数将依赖关系注入到对象中。
② Setter注入:通过Setter方法对属性进行赋值,实现依赖关系的注入。
③ 注解注入:通过反射为属性赋值,实现依赖关系的注入。
依赖注入的时机通常发生在IoC容器完成Bean定义资源的定位、载入、解析和注册之后。在初始化IoC容器完成之后,非懒加载的BeanDefinition会被实例化和进行依赖注入。对于懒加载的Bean对象,其依赖注入发生在用户第一次调用getBean()方法时。
三 简单demo
1 为Maven项目添加依赖
pom
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--包含了spring所需core中的核心依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
</dependencies>
2 实体类
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void doWork(){
System.out.println(this.name+"准备出去玩!");
}
}
3 resources目录
spring-ioc.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">
<!--使用IOC创建对象: Person person=new Person();-->
<!--
id表示创建对象的唯一标识
class表示对象实体类全类名
-->
<bean id="person" class="cn.tj.Person" >
<!--
给变量赋值:person.setName("叶凡");
name实体类成员变量名称
value给成员变量设置的值
-->
<property name="name" value="叶凡"></property>
</bean>
</beans>
4 测试方法
@Test
public void play_ioc(){
//加载spring配置文件 这是一个接口
ApplicationContext context=
new ClassPathXmlApplicationContext("spring-ioc.xml");
// 调用获取bean的方法:参数是配置文件设置的bean标签的id值
// 将返回类型为Object的对象强转为Person
// Person person = (Person) context.getBean("person");
// 推荐使用
Person person = context.getBean(Person.class, "person");
// Person person = context.getBean(Person.class);
//调用对象的成员方法
person.doWork();
}
5 ApplicationContext
BeanFactory是Spring 最底层的接口,提供IoC 功能,负责创建、组装、管理 bean,而ApplicationContext在继承了BeanFactory的同时,还提供 AOP 集成、事件传播、统一资源加载等功能。bean就是Spring IoC 容器管理的对象
6 Spring 配置方式
① XML配置:Spring早期主要采用XML方式进行配置,通过编写配置文件来定义Bean以及它们的依赖关系。这种方式易于理解和维护,但在配置文件过于庞大时会降低可读性。
② 注解配置:从Spring 3.0开始,注解配置成为可能,它通过Java注解来定义应用程序的组件和依赖关系。注解配置相比XML方式更为简洁,易于阅读和维护,适合用于简单的Bean配置。
③ Java Config配置:这是一种灵活的配置方式,通过Java代码来定义应用程序的组件和依赖关系。这种方式提供了一种更直接的方式来配置Bean,使得代码更加清晰和易于理解。
④ 基于Java的XML配置:这种方式结合了XML和Java代码的优点,可以在XML文件中定义Bean,同时使用Java代码进行依赖注入。这种方式适用于需要使用XML但同时又希望保持代码简洁的情况。
四 Spring 整合单元测试
1 优势
① 高度可控性:使用Spring的测试工具,可以轻松模拟和控制应用程序中的各个组件,从而更好地进行单元测试,减少对外部依赖的影响。
② 方便的依赖注入:Spring框架提供了依赖注入的功能,使得测试代码中的依赖关系更加清晰和易于管理。同时,使用Spring的单元测试框架可以自动装配依赖对象,减少了手动创建和配置对象的工作量。
③ 对原有单元测试能力的支持:Spring框架对Junit和TestNG等原有的单元测试框架提供了良好的支持,用Spring 容器管理测试代码可以方便地编写和执行测试用例。而传统测试用测试代码管理 Spring 容器每个测试都要重新启动 Spring 容器,十分消耗服务器资源。
④ 方便的测试管理:通过Spring的单元测试框架,可以使用各种监听器对测试类的依赖注入、对Spring applicationContext的访问以及事务管理能力进行管理,为使用Spring架构的应用程序的测试带来了极大的便利性。
综上所述,使用Spring整合单元测试可以提高测试的效率和准确性,降低测试的复杂度和工作量,方便地管理依赖关系和测试数据,以及更好地控制应用程序的行为。
2 demo
① pom 添加依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.8.RELEASE</version>
<scope>test</scope>
</dependency>
② 测试方法
//spring整合junit4
@RunWith(SpringJUnit4ClassRunner.class)
//读取项目下的多个配置文件
//@ContextConfiguration(locations = {"classpath:spring-ioc.xml","",""})
//项目下只有一个配置文件读取: ApplicationContext context= new ClassPathXmlApplicationContext("spring-ioc.xml");
//classpath表示从编译后的资源根目录下获取
@ContextConfiguration("classpath:spring-ioc.xml")
//不写locations会去测试类的路径找测试类名-context.xml配置文件
//@ContextConfiguration
public class PersonTestSpring {
// 使用注解将容器的bean注入到当前类中:相当于 ioc容器.getBean("person");
@Autowired
private Person person;
@Test
public void hello(){
// 调用bean的成员方法
// person.doWork();
System.out.println(person);
}
}
③ spring-ioc.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="person" class="cn.tj.domain.Person" >
<!-- <property name="name" value="叶凡"></property>-->
</bean>
</beans>