当前位置:   article > 正文

JavaEE企业级应用开发教程——第六章 初识Spring框架(黑马程序员第二版)(SSM)_javaee企业级应用开发教程第二版pdf

javaee企业级应用开发教程第二版pdf

第六章 初识Spring框架

6.1 Spring介绍

6.1.1 Spring概述

早期Java EE规范较为复杂,其中EJB标准设计存在缺陷,导致开发复杂,代码侵入性强,部署测试困难。

因此,Spring于2003年诞生。Spring是一个轻量级的一站式Java SE/EE开源框架,最核心的理念是控制反转和面向切面编程。其中,控制反转是Spring的基础,支持Java Bean管理;面向切面编程是Spring的重要特性,可以在运行期间动态代理,为程序添加功能。

Spring涵盖了表现层、业务逻辑层和持久层,提供了SpringMVC框架、事务管理、日志记录、整合MyBatis、Hibernate等技术。尽管Spring贯穿于各个层,但它不是为了取代已有框架,而是为了与它们进行无缝整合,具有高度的开放性。


6.1.2 Spring框架的优点

Spring框架有以下优点:

  1. 非侵入式设计:Spring框架不会强制要求开发者使用特定的类继承关系或接口,这使得开发者可以更自由地使用其他Java技术,并且避免了对原有代码的侵入。

在软件开发中,非侵入式(non-invasive)指的是一个框架或库的使用方式不需要对应用程序做出大量的修改或扩展。相反,应用程序可以通过配置或者编写少量代码来使用该框架或库。

举个生活中的例子,假设你想要更换你家的电视机,你可以选择购买一台新的电视机来替换旧的,这种方式就是“侵入式”的。而另一种方式是使用一个支架来安装一个投影仪,这样你就可以将电视节目投射到墙上观看,而不必更换电视机。这种方式就是“非侵入式”的,因为它不需要对原有的家庭设备做出大量修改或扩展,而是通过一个小的组件来实现目标。同样的,Spring框架也提供了一种非侵入式的方式来管理应用程序的组件。

  1. 降低耦合性,方便开发:Spring框架通过控制反转(IoC)和依赖注入(DI)实现了组件之间的松散耦合,使得组件之间的关系更加简单、清晰,并且易于维护和测试。

  2. 支持AOP编程:Spring框架支持面向切面编程(AOP),这使得开发者可以方便地在不修改源代码的情况下,为程序统一添加功能。

  3. 支持声明式事务:Spring框架提供了声明式事务管理的支持,使得开发者可以更方便地管理事务,从而减少了代码的重复和复杂度。

  4. 方便程序的测试:Spring框架提供了基于Junit的单元测试支持,并且通过依赖注入,可以很方便地模拟和测试不同的对象和组件。

  5. 方便集成各种优秀框架:Spring框架通过提供各种模板和API,使得开发者可以很方便地集成其他优秀的框架和技术,如Hibernate、MyBatis等。

  6. 降低JAVAEE API的使用难度:Spring框架通过对JAVAEE API的封装和简化,使得开发者可以更加简单、方便地使用各种JAVAEE API。


6.1.3 Spring的体系结构

Spring是模块化的,可以只选用想用的模块。体系结构图:
在这里插入图片描述


Spring 主要分为八大模块,其中,绿色背景的模块是 Spring 的主要模块,也是本书重点讲解的模块,下面对这些模块进行简单介绍。

1. 核心容器(Core Container)

核心容器模块在Spring的功能体系中起着支撑作用,是其他模块的基石。

  1. Beans模块:该模块提供了创建和管理Bean对象的功能,其中BeanFactory类是工厂模式的经典实现。Beans模块的主要作用是管理Bean对象的生命周期,并提供了一系列接口和类用于支持Bean的创建、销毁、后置处理等操作。

  2. Core模块:该模块提供了Spring框架的基本组成部分,包括IoC和DI功能。IoC(Inversion of Control)是一种设计模式,通过将对象的创建和依赖关系的管理委托给容器来实现对象的解耦和灵活的配置方式。而DI(Dependency Injection)则是IoC的具体实现方式,它通过容器将Bean的依赖关系注入到Bean中,从而实现对象的解耦和灵活的配置方式。

  3. Context模块:该模块构建于Beans模块和Core模块的基础上,它可以通过ApplicationContext接口提供上下文信息。ApplicationContext是Spring IoC容器的具体实现,它提供了一系列功能,包括Bean的生命周期管理、资源管理、国际化支持、事件机制等。Context模块还提供了一些特殊的ApplicationContext实现,如WebApplicationContext和AnnotationConfigApplicationContext等。

  4. SpEL模块:该模块是Spring3.0后新增的模块,它提供了对SpEL(Spring Expression Language)的支持。SpEL是一个在程序运行时支持操作对象图的表达式语言,可以用于在配置文件中引用Bean、访问Bean的属性、调用Bean的方法等。SpEL还提供了一些特殊的表达式,如条件表达式、正则表达式、集合投影等,可以帮助开发者更灵活地配置和管理Bean对象。


2.数据访问及集成(Data Access/Integration)

数据访问及集成模块用于访问和操作数据库中的数据,它主要包含JDBC模块、ORM模块、OXM模块、JMS模块和Transactions模块。

  1. JDBC模块:该模块提供了一个JDBC的抽象层,可以消除长的JDBC编码并能够解析数据库供应商特有的错误代码。它还提供了一些实用工具类和接口,如JdbcTemplate和DataSource等,用于简化JDBC编程。

  2. ORM模块:该模块为主流的对象关系映射API提供了集成层,用于集成主流的对象关系映射框架,如MyBatis、Hibernate和JDO等。ORM模块还提供了一些实用工具类和接口,如HibernateTemplate和JpaTemplate等,用于简化ORM编程。

  3. OXM模块:该模块提供了对XML映射的抽象层的支持,如JAXB、Castor、XML Beans、JiBX和XStream等。它还提供了一些实用工具类和接口,如Marshaller和Unmarshaller等,用于简化XML编程。

  4. JMS模块:该模块主要用于传递消息,包含消息的生产和消费。自Spring4.1版本后,JMS模块支持与Spring message模块的集成,可以更方便地使用消息驱动的应用程序。

  5. Transactions模块:该模块的主要功能是事务管理,它支持Spring自动处理的声明式事务,可以通过注解或XML配置来声明事务。Transactions模块还提供了一些实用工具类和接口,如TransactionTemplate和TransactionManager等,用于简化事务编程。


3.Web

Web模块是Spring框架中的重要组成部分,它的实现基于ApplicationContext,提供了Web应用的各种工具类,包括WebSocket模块、Servlet模块、Web模块和Portlet模块。下面是对每个模块的介绍和功能分点说明:

  1. WebSocket模块:该模块是Spring4.0以后新增的模块,它提供了WebSocket和SockJS的实现,以及对STOMP的支持。WebSocket是一种基于TCP协议的全双工通信协议,可以在浏览器和服务器之间建立持久性连接,用于实时通信和数据传输。

  2. Servlet模块:该模块提供了Spring的模型、视图、控制器,以及Web应用程序的REST Web服务实现。它还提供了一些实用工具类和接口,如DispatcherServlet和HandlerMapping等,用于简化Web应用程序的开发和维护。

  3. Web模块:该模块提供了针对Web开发的集成特性,如大部分文件上传功能等。此外,Web模块还包含一个HTTP客户端和Spring远程处理支持的Web相关部分。它还提供了一些实用工具类和接口,如WebMvcConfigurer和WebApplicationContext等,用于简化Web应用程序的配置和管理。

  4. Portlet模块:该模块提供了对Portlet规范的支持,可以将Spring应用程序部署为Portlet应用程序。它还提供了一些实用工具类和接口,如PortletContext和PortletRequest等,用于简化Portlet应用程序的开发和维护。


4. 其他模块

Spring框架还有其他几个重要的模块,包括AOP模块、Aspects模块、Instrumentation模块、Messaging模块和Test模块。下面是对每个模块的介绍和功能分点说明:

  1. AOP模块:该模块提供了对面向切面编程的支持,程序可以定义方法拦截器和切人点,将代码按照功能进行分离,以降低程序的耦合性。AOP模块可以与其他Spring模块和第三方库进行集成,可以用来实现日志记录、性能监控、事务管理等功能。

  2. Aspects模块:该模块提供了与AspectJ集成的支持,AspectJ是一个功能强大且成熟的AOP框架,为面向切面编程提供了多种实现方法。Aspects模块可以用于实现复杂的切面需求,如异常处理、缓存、安全性等。

  3. Instrumentation模块:该模块提供了对类工具的支持,并且实现了类加载器,该模块可以在特定的应用服务器中使用。Instrumentation模块可以用于对Java应用程序进行监控和调试,例如对类加载过程进行增强和修改。

  4. Messaging模块:该模块是Spring4.0以后新增的模块,它提供了对消息传递体系结构和协议的支持。Messaging模块可以用于实现异步消息通信、事件驱动架构等应用场景。

  5. Test模块:该模块提供了对程序单元测试和集成测试的支持。Test模块可以自动化测试Spring应用程序,包括依赖注入、AOP、事务管理等方面的测试。Test模块还提供了一些实用工具类和接口,如MockMvc和TestRestTemplate等,用于简化测试代码的编写和管理。


6.1.4 Spring 5的新特性

Spring 5 是 Spring 框架的最新版本,相比于旧版本,它对核心框架进行了修订和更新,引入了很多新特性。其中,主要体现在以下几个方面:

  1. 更新 JDK 基线:Spring 5 运行于 JDK 8 之上,因此要求 JDK 最低版本为 8,这促进了 Spring 开发者积极运用 Java 8 的新特性。

  2. 修订核心框架:Spring 5 利用 JDK 8 的新特性进行自身功能的修订,包括反射增强、基于 JDK 8 的默认方法构建的选择性声明、@Nullable 和 @NotNull 注解等。

  3. 更新核心容器:Spring 5 支持候选组件索引作为类路径扫描的替代方案,从而缩减了 Spring 程序的启动时间。

  4. 支持响应式编程:Spring 5 包含了响应流和 Reactor 的实现,以及对 ReactiveStream 的 Java 实现 IReactor 的支持,这使得 Spring 更加灵活,能够构建对事件做出响应的应用程序。

  5. 支持函数式 Web 框架:Spring 5 提供了一个函数式 Web 框架,使用函数式编程风格来定义端点,引入了 HandlerFunction 和 RouterFunction 两个基本组件。

  6. 支持 Kotlin:Spring 5 对 Kotlin 语言进行了支持,这拓宽了 Spring 的应用领域,让开发人员可以进行深度的函数式编程。

  7. 提升测试功能:Spring 5 完全支持 JUnit 5 Jupiter,同时提供了在 SpringTestContext Framework 中进行并行测试的扩展,针对响应式编程模型,引入了支持 Spring WebFlux 的 WebTestClient 集成测试。


6.1.5 Spring的下载及目录结构

Spring Framework 是一个开源的 Java 应用程序框架,可以通过官方网站进行下载。

下载页面提供了多个版本的 Spring Framework,开发者可以根据自己的需求选择合适的版本进行下载,同时也可以下载相关的依赖库等。

Spring Framework 的目录结构主要包含以下几个部分:

  1. bin:包含可执行文件,如 spring.bat、spring.sh 等。

  2. conf:包含配置文件,如 spring.xml、spring.properties 等。

  3. docs:包含 API 文档及其他文档。

  4. lib:包含 Spring Framework 的所有依赖库及其他必要的 JAR 包,如 spring-core.jar、spring-webmvc.jar 等。

  5. samples:包含 Spring Framework 的示例应用程序及示例代码。

  6. src:包含 Spring Framework 的源代码。

  7. dist:包含编译好的 Spring Framework 发布版本。

在使用 Spring Framework 时,一般只需要引入相应的 JAR 包即可,而不需要手动复制或管理目录结构。


6.2 Spring的入门程序

前面学习了Spring的基础知识,下面通过一个简单的人门程序演示 Spring架的使用,该人门程序要求在控制台打印“张三:欢迎来到Spring”,具体实现步骤如下。

1. 创建 Maven 项目

在 IDEA 中创建一个名称为 chapter06 的 Maven 项目,可以选择使用 IDE 提供的 Maven 项目模板来创建。

2. 配置 pom.xml 文件

在项目的 pom.xml 文件中添加 Spring 的依赖,包括 spring-core、spring-beans、spring-context、spring-expression 和 commons-logging 等依赖包。可以直接复制下面的依赖配置到 pom.xml 文件中:

<dependencies>
<!-- Spring的核心依赖包,包含Spring框架的基础功能 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>

<!-- Spring的bean依赖包,包含Spring框架的IoC和DI功能 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>

<!-- Spring的上下文依赖包,包含Spring框架的上下文(Context)功能 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>

<!-- Spring的表达式语言依赖包,包含Spring框架的表达式语言功能 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-expression</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>

<!-- Commons Logging是一个通用的日志框架,为许多日志系统提供了一个简单的抽象层 -->
<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>
</dependencies>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

3. 创建 HelloSpring 类

在项目的 src/main/java 目录下创建一个名为 com.itheima 的包,并在该包下创建一个名为 HelloSpring 的类。在 HelloSpring 类中定义一个名为 userName 的属性和一个名为 show 的方法,具体代码如下:

package com.itheima;

public class HelloSpring {
    private String userName; // 定义一个字符串类型的属性

    // setter方法,用于设置属性值
    public void setUserName(String userName) {
        this.userName = userName;
    }

    // 定义一个方法,用于输出欢迎信息
    public void show() {
        System.out.println(userName + ": 欢迎来到 Spring!");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

4. 创建 applicationContext.xml 配置文件

在项目的 src/main/resources 目录下创建一个名为 applicationContext.xml 的配置文件,并在该文件中定义名为 helloSpring 的 Bean。具体代码如下:

<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-3.0.xsd">

    <!-- 定义一个id为helloSpring的Bean,指定其class为com.itheima.HelloSpring -->
    <bean id="helloSpring" class="com.itheima.HelloSpring">
        <!-- 设置helloSpring的userName属性为"张三" -->
        <property name="userName" value="张三"/>
    </bean>

</beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

5. 创建测试类 TestHelloSpring

在项目的 com.itheima 包下创建一个名为 TestHelloSpring 的测试类,在 main 方法中初始化 Spring 容器并加载 applicationContext.xml 配置文件,然后通过 Spring 容器获取 HelloSpring 类的实例并调用 show 方法输出信息。具体代码如下:

package com.itheima;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestHelloSpring {
    public static void main(String[] args) {
        // 初始化 Spring 容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 获取 HelloSpring 实例
        HelloSpring helloSpring = (HelloSpring) context.getBean("helloSpring");
        // 调用 show 方法输出信息
        helloSpring.show();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

6. 运行程序

运行 TestHelloSpring 类,程序将在控制台输出“张三: 欢迎来到 Spring!”的信息。

以上就是使用 Spring 架构实现一个简单的 HelloWorld 程序的具体实现步骤。


6.3 控制反转与依赖注入

6.3.1 控制反转的概念

控制反转(IoC)是一种设计原则,用于降低程序代码之间的耦合度。在传统面向对象编程中,应用程序需要主动创建相关的对象,这样会导致类与类之间高耦合,并且难以测试。而IoC则是通过将对象的创建、管理和调用交给容器来完成,从而降低了组件之间的耦合性,提高了代码的可重用性、可扩展性和可维护性。同时,IoC容器负责控制程序之间的关系,控制权发生了反转,即控制权由应用代码转移到了IoC容器。

在使用Spring框架时,对象的实例不再由调用者来创建,而是由Spring的IoC容器来创建。IoC容器会负责控制程序之间的关系,而不是由调用者的程序代码直接控制。这样,控制权由应用代码转移到了IoC容器,控制权发生了反转,这就是Spring的控制反转。

IoC设计原则是借助于IoC容器实现具有依赖关系对象之间的解,各个对象类封装之后,通过IoC容器来关联这些对象类。这样对象类与对象类之间就通过IoC容器进行联系,而对象类与对象类之间没有什么直接联系。因此,IoC容器是实现IoC的关键,它负责管理组件之间的依赖关系,实现了控制反转。Spring框架就是一个典型的IoC框架,它通过IoC容器来管理组件之间的依赖关系。

IoC能够降低组件之间的耦合性,因为它将对象的创建、管理和调用交给容器来完成,使得组件之间不再直接依赖于彼此,而是通过容器来进行协调。这样可以使得组件之间的关系更加松散,从而提高代码的可重用性、可扩展性和可维护性。

举个生活中的例子,考虑一家餐厅的厨房和服务员之间的关系。在传统的餐厅中,厨师们会根据服务员的点单来主动准备菜品,服务员会负责将菜品送到客人的桌子上。这种方式下,厨师和服务员之间的耦合度很高,他们需要密切合作才能完成工作。如果其中任何一个人出了问题,整个服务都会受到影响。

现在考虑采用IoC的方式来组织餐厅的工作流程。可以引入一个菜单管理系统,服务员只需要将客人的点单输入到菜单管理系统中,系统会自动将订单发送到厨房,并且根据厨房的状况来调整订单的优先级。厨师们只需要按照系统的提示来准备菜品,不需要跟服务员直接交流。这样,厨师和服务员之间的联系就通过菜单管理系统来进行了协调,他们之间的耦合度得到了降低,整个餐厅的工作效率也得到了提高。这就是IoC的一个生活中的例子。

在这里插入图片描述


6.3.2 依赖注入的概念

依赖注入(DI)是IoC的一种实现方式,它是指在运行期间动态地将某种依赖资源注入到对象中,例如将对象B注入到对象A的成员变量中。DI的基本思想是,明确地定义组件接口,独立开发各个组件,然后根据组件的依赖关系组装运行。

DI和IoC是从不同的角度来描述同一件事情。IoC是从IoC容器的角度来描述,即IoC容器控制应用程序,由IoC容器反向地向应用程序注入所需要的外部资源;而DI是从应用程序的角度来描述,即应用程序依赖IoC容器创建并注入它所需要的外部资源。

在实现DI时,通常会将依赖资源的注入方式抽象成一个接口或者抽象类,然后由IoC容器来实现这个接口或者抽象类,从而实现依赖资源的注入。这样可以使得应用程序更加灵活,便于扩展和维护。

举个例子,假设一个应用程序需要一个数据库连接对象来进行数据访问,而这个数据库连接对象需要在运行期间动态地注入到应用程序中。通过DI的方式,应用程序可以定义一个接口来表示数据库连接对象,然后将这个接口作为依赖注入到应用程序中需要使用数据库连接对象的组件中。在运行期间,IoC容器会根据配置文件或者其他方式创建一个具体的数据库连接对象,并将这个对象注入到需要使用数据库连接对象的组件中。这样,应用程序就可以实现对数据库连接对象的依赖注入,从而实现了应用程序的解耦和灵活性。

再举个例子
假设你要去超市购物,你需要购买一些蔬菜、水果和面包。你可以选择自己去超市挑选商品,然后把它们放到购物车里,最后结账。这个过程非常繁琐,需要你自己去选择商品,然后将它们放到购物车里,再到收银台结账。

现在,假设超市提供了一种新的服务,叫做“代购服务”。你只需要告诉代购员你要购买的商品,代购员就会为你挑选商品,并把它们放到购物车里,最后帮你结账。这个过程非常方便,你只需要告诉代购员你要购买的商品,然后等待代购员为你完成购物。

在这个例子中,代购员就相当于一个实现了“购物服务”的对象,它能够根据你的要求来为你挑选商品,并把它们放到购物车里。你只需要告诉代购员你要购买的商品,而不需要关心代购员是如何为你挑选商品的。这样,你就可以实现对购物过程的解耦和灵活性,从而更加方便地完成购物。

这个例子中,代购员就是一个控制反转(IoC)的实现。代购员负责为你挑选商品和结账,而你只需要告诉代购员你要购买的商品,而不需要关心代购员是如何实现这个过程的。代购员就像是一个依赖对象,你只需要将你的购物需求告诉它,它就会完成购物过程。代购员的实现就像是一个依赖注入(DI)的过程,代购员依赖于你的购物需求,并根据这个需求来完成购物过程。这样,你就可以实现对购物过程的解耦和灵活性,从而更加方便地完成购物。超市提供了代购员这一“依赖对象”,可以说超市是“IoC容器”。


6.3.3 依赖注入的类型

依赖注入(Dependency Injection,DI)指的是使用Spring框架创建对象时,动态地将其所依赖的对象注入到Bean组件中。依赖注入有两种实现方式,一种是构造函数注入,另一种是属性或者setter方法注入。

Bean就是一个Java类,它可以被Spring容器所管理和配置。通常情况下,一个Bean对应着一个Java类,但是在Spring框架中,一个Java类也可以定义为多个Bean组件,这取决于开发人员的设计和配置。


1. 构造方法注入

构造方法注人是指 Spring容器调用构造方法注人被依赖的实例,构造方法可以是有参的或者是无参的。Spring 在读取配置信息后,会通过反射方式调用实例的构造方法,如果是有参构造方法,可以先在构造方法中传人所需的参数值,然后创建类对象。

下面通过案例演示构造方法注入的实现,具体步骤如下。

  1. 编写用户类

在项目的com.itheima包下新建User类,在User类中定义id、name和password这3个属性。User类的具体代码如下:


```java
public class User {
    private int id;
    private String name;
    private String password;

    public User(int id, String name, String password) {
        this.id = id;
        this.name = name;
        this.password = password;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

  1. 配置Bean的信息

在项目的src/main/resources目录下创建applicationContext-User.xml文件,在该文件中添加User类的配置信息,把User类注册为一个Bean组件,具体代码如下:

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

    <!-- 配置User Bean -->
    <bean id="user" class="com.itheima.User">
        <constructor-arg name="id" value="1" />
        <constructor-arg name="name" value="张三" />
        <constructor-arg name="password" value="123456" />
    </bean>

</beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在上述配置中,我们定义了一个id为user的Bean组件,其对应的Java类为com.itheima.User。通过元素向构造方法中传递了id、name和password这3个参数值。

  1. 编写测试类

在项目的com.itheima包下创建测试类TestUser,具体代码如下:

public class TestUser {
    public static void main(String[] args) {
        // 创建 Spring 容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext-User.xml");

        // 获取 User Bean
        User user = (User) ac.getBean("user");

        // 输出 User 的信息
        System.out.println(user);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在上述测试类中,我们首先创建了Spring容器(IoC容器),并通过该容器获取了id为user的Bean组件。然后,我们输出了该Bean组件的信息,包括其id、name和password等属性值。

通过上述步骤,我们成功地实现了构造方法注入。在实际项目中,我们可以通过这种方式实现依赖注入,从而将依赖对象注入到Bean组件中,提高代码的可维护性和可扩展性。


2.属性setter方法注入

属性setter 方法注入是 Spring最主流的注入方法,这种注入方法简单、直观,它是在被注入的类中声明一个setter 方法,通过setter 方法的参数注入对应的值。

下面通过一个案例演示属性 setter 方法注人的实现,具体步骤如下。

  1. 编写用户对象类

在项目的com.itheima包下新建User2类,在User2类中定义id、name和password这3个属性,并提供对应的setter方法。User2类的具体代码如下:

public class User2 {
    private int id;
    private String name;
    private String password;

    public void setId(int id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User2{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

在上述代码中,我们定义了id、name和password这3个属性,并为每个属性提供了对应的setter方法。


  1. 获取Bean的配置信息

在项目的src/main/resources目录下创建applicationContext-User2.xml文件,并在该文件的元素中添加User2类的配置信息,具体代码如下:

<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="user2" class="com.itheima.User2">
        <property name="id" value="1"/>
        <property name="name" value="Tom"/>
        <property name="password" value="123456"/>
    </bean>

</beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

在上述代码中,我们使用元素定义了一个名为"user2"的Bean,该Bean的类为User2,同时通过元素为User2类的id、name和password属性注入了对应的值。


  1. 编写测试类

在项目的com.itheima包下创建测试类TestUser2,具体代码如下:

public class TestUser2 {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-User2.xml");
        User2 user2 = (User2) context.getBean("user2");
        System.out.println(user2);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在上述代码中,我们使用ApplicationContext接口的实现类ClassPathXmlApplicationContext加载了配置文件applicationContext-User2.xml,并通过调用getBean方法获取了名为"user2"的Bean对象。最后,我们打印了该对象的属性值,输出结果如下:

User2{id=1, name=‘Tom’, password=‘123456’}

通过上述案例,我们可以看到,使用属性setter方法注入的方式,可以通过元素为Bean对象的属性注入对应的值,从而实现IOC容器对Bean对象的管理和注入。这种方式简单、直观,是Spring最主流的注入方式之一。


6.3.4 依赖注入的应用

以下是一个使用属性 setter 方法注入实现简单登录验证的示例,具体实现步骤如下:

  1. 编写 DAO 层

我们先编写一个 UserDAO 接口,定义用户数据访问方法:

public interface UserDAO {
    User getUserByUsername(String username);
}
  • 1
  • 2
  • 3

然后,我们编写一个 UserDAOImpl 类,实现该接口:

public class UserDAOImpl implements UserDAO {
    private DataSource dataSource;

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Override
    public User getUserByUsername(String username) {
        // 使用 dataSource 访问数据库,获取用户信息
        // 省略具体实现代码
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在 UserDAOImpl 类中,我们使用属性 setter 方法注入了一个 DataSource 对象,以便访问数据库。


  1. 编写 Service 层

接下来,我们编写一个 UserService 类,实现登录验证逻辑:

public class UserService {
    private UserDAO userDAO;

    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }

    public boolean login(String username, String password) {
        User user = userDAO.getUserByUsername(username);
        if (user == null) {
            return false;
        }
        return user.getPassword().equals(password);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在 UserService 类中,我们使用属性 setter 方法注入了一个 UserDAO 对象,以便访问用户数据。

  1. 编写 applicationContext.xml 配置文件

接下来,我们需要在 Spring 的配置文件中定义 UserService 和 UserDAO 的实例,并将它们进行关联。具体实现如下:

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/mydb" />
    <property name="username" value="root" />
    <property name="password" value="mypassword" />
</bean>

<bean id="userDAO" class="com.example.UserDAOImpl">
    <property name="dataSource" ref="dataSource" />
</bean>

<bean id="userService" class="com.example.UserService">
    <property name="userDAO" ref="userDAO" />
</bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

在配置文件中,我们首先定义了一个 DataSource 对象,以便访问数据库。然后,我们定义了一个 UserDAOImpl 实例,并将其属性 dataSource 设置为前面定义的 DataSource 对象。最后,我们定义了一个 UserService 实例,并将其属性 userDAO 设置为前面定义的 UserDAOImpl 对象。


  1. 编写测试类

最后,我们编写一个测试类,测试登录验证逻辑是否正确:

public class TestLogin {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) context.getBean("userService");
        boolean result = userService.login("admin", "admin123");
        System.out.println("Login result: " + result);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在测试类中,我们首先加载 Spring 的配置文件,然后获取 UserService 实例,并调用其 login 方法进行登录验证。最后,我们输出登录验证结果。


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/384715
推荐阅读
相关标签
  

闽ICP备14008679号