Spring 框架由Rod Johnson 开发, 2004年发布了Spring 框架的第一个版本。经过十多年的发展,Spring 己经发展成Java EE 开发中最重要的框架之一。不仅如此,围绕Spring ,以Spring 为核心还衍生出了一系列框架,如Spring Web Flow 、Spring Security、
Spring Data 、Spring Boot 、Spring Cloud 等。
Spring 为企业应用的开发提供了一个轻量级的解决方案。该解决方案包括: 基于依赖注入的核心机制、基于AOP 的声明式事务管理、与多种持久层技术的整合,以及优秀的Web MVC 框架等。Spring致力于Java EE 应用各层的解决方案,而不是仅仅专注于某一层的方案。可以说: Spring 是企业应用开发的“ 一站式”选择, Spring 贯穿表现层、业务层、持久层。
当使用Spring 框架时,必须使用Spring Core Container (即Spring 容器),它代表了Spring框架的核心机制, Spring Core Container 主要由org.springframework.core 、
org.springframework.beans 、org.springframework. context 和org.springframework . expression 四个包及其子包组成,主要提供Spring IoC 容器支持。其中org. springframework. expression 及其子包是Spring 3.0 新增的,它提供了Spring Expression Language 支持。
Spring 5.0
与之前的Spring 版本相比, Spring 5.0 发生了一些变化,这些变化包括:Spring 5.0 整个框架己经全面基于Java 8,因此Spring 5.0 对JDK 的最低要求就是Java 8。Spring 5.0
可以在运行时支持Java 9 。因为Java 8的反射增强,因此Spring 5.0框架可以对方法的参数进行更高效的访问。Spring 5.0 核心接口己加入了Java 8 接口支持的默认方法。Spring 5.0 框架己经自带了通用的日志封装,因此不再需要额外的common- logging日志包。当
然,新版的日志封装也会对Log4j 2.x、SLF4J 、JUL ( java.util.logging 进行自动检测。引入@Nullable 和@NotNull 注解来修饰可空的参数以及返回值,避免运行时导致NPE 异常。Spring 5.0 框架支持使用组件索引来扫描目标组件,使用组件索引扫描比使用类路径扫描更高效。Spring 5.0 框架支持JetBrains Kotlin 语言。Spring 5.0 的Web 支持己经升级为支持Servlet 3.1 以及更高版本的规范。Spring 5.0 的升级主要就是全面基于Java 8 ,并在运行时支持Java 9 和Servlet 3.1规范,也为核心IoC 容器增强了一些注解,并通过组件索引扫描来提升运行效率。
Spring 入门
Spring 是一个独立的框架,它不需要依赖于任何Web 服务器或容器,它既可在独立的Java SE 项目中使用,当然也可在Java Web 项目中使用。下面先介绍如何为Java 项目和Java Web 项目添加Spring支持。
如果需要友布使用了Spring 框架的Java Web 项目,还需要将Spring 框架的JAR 包( 21
个JAR 包)添加到Web 应用的WEB-INF 路径下。
使用Spring 管理Bean:
Spring 核心容器的理论很简单: Spring 核心容器就是一个超级大工厂,所有的对象(包括数据源、Hibernate SessionFactory 等基础性资源〉都会被当成Spring 核心容器管理的对象一 Spring 把容器中的一切对象统称为Bean 。Spring 容器中的Bean,与以前昕过的Java Bean 是不同的。不像Java Bean,必须遵守一些特定的规范,而Spring 对Bean 没有任何要求。只要是一个Java 类, Spring 就可以管理该Java 类,并将它当
成Bean 处理。对于Spring 框架而言, 一切Java 对象都是Bean。
使用Spring 框架之后, Sp ring 核心容器是整个应用中的超级大工厂,所有的Java 对象都交给Spring容器管理一一这些Java 对象被统称为S pring 容器中的Bean 。
现在的问题是: Spring 容器怎么知道管理哪些Bean 呢? 答案是XML 配置文件( 也可用注解, 后面会介绍), Spring 使用XML 配置文件来管理容器中的Bean 。因此,接下来为该项目增加XML 配置文件, Spring 对XML 配置文件的文件名没有任何要求,读者可以随意指定。
该配置文件的根元素是<beans … ./>,根元素主要就是包括多个<bean… ./>元
素, 每个<bean… ./>元素定义一个Bean 。上面配置文件中一共定义了4 个Bean,其中前两个Bean 是本示例提供的Axe 和Person 类:而后两个Bean 则直接使用了JDK 提供的j ava. util.Date 和javax.swing.JFrame。
实际上,配置文件中的<bean … ./>元素默认以反射方式来调用该类无参数的构造器,Spring 框架解析该<bean … ./>元素后将可以得到两个字符串,其中idStr 的值为”person”(解析<bean… ./>元素的id 属性得到的值) , classStr 的值为”org.crazyit叩p .service.Person”(解析<bean… ./>元素的class 属性得到的值〉。
通过上面的反射代码还可以得到一个结论:在Spring 配置文件中配置B ean 时, class 属性的值必须是Bean 实现类的完整类名(必须带包名)),不能是接口,不能是抽象类(除非有特殊配置〉, 否则Spring无法使用反射创建该类的实例。
上面配置文件中还包括一个<property.. ./>子元素,<property.../>子元素通常用于作为<bean… ./>元素的子元素,它驱动Spring 在底层以反射执行一次se忧er 方法。其中<property. ./>的name 属性值决定执行哪个setter 方法,而value 或ref 决定执行setter 方法的传入参数。
Spring 框架只要看到<property. ../>子元素, Spring 框架就会在底层以反射方式执行一次se忧er 方法。何时执行这个se忧er 方法呢?该Bean 一旦创建处理, Spring 会立即根据<property… ./>子元素来执行setter方法。也就是说,<bean… ./>元素驱动Spring 调用构造器创建对象: <property.. ./>子元素驱动Spring 执行setter 方法,这两步是先后执行的,中间几乎没有任何间隔。
配置中<property… ./>元素的name 属性值为axe ,该元素将驱动Spring以反射方式执行person Bean 的setAxe方法: ref 属性值为axe ,该属性值指定以容器中名为axe 的Bean 作为执行setter方法的传入参数。
接下来程序就可通过Spring 容器来访问容器中的Bean, ApplicationContext 是Spring 容器最常用的接口,该接口有如下两个实现类。
对于Java 项目而言,类加载路径总是稳定的,因此通常总是使用ClassPathXmlApplicationContex创建Spring 容器。
上面程序中第1 行粗体字代码创建了Spring 容器,第2 行粗体字代码通过Spring 容器获取i d为person 的Bean一Spring 容器中的Bean ,就是Java 对象。
程序不再使用new 调用构造器创建Java 对象,所有的Java 对象都由Spring 容器负责创建。