深入浅出讲解Spring框架中依赖注入与控制反转及应用

yizhihongxing

深入浅出讲解Spring框架中依赖注入与控制反转及应用

什么是依赖注入和控制反转

在传统的 Java 应用中,在一个类中如果需要依赖另一个类的对象,我们通常会使用“new”关键字手动创建这个对象。例如:

public class UserService {

    private UserDao userDao = new UserDao();

    // 其他方法
    // ...
}

这种方式虽然简单,但是有一个缺点,就是这样耦合度高、扩展性差。例如如果 UserDao 的实现类需要变更,我们需要在所有依赖 UserDao 的业务类中修改代码。而且对于不同的环境,我们还需要手动修改代码。

此时依赖注入和控制反转就要登场了。

  • 依赖注入(Dependency Injection)是指,通过引入 IoC 容器,在容器中动态加载对象,并将这些对象注入到需要使用它们的类中,从而实现对象与对象之间的解耦。
  • 控制反转(Inversion of Control,IoC)是指,将对象的控制权由程序员转移到框架中,由框架帮我们管理对象的声明周期和依赖关系,从而实现程序的解耦。

Spring 中的依赖注入和控制反转

在 Spring 中,我们使用 BeanFactory 或者 ApplicationContext 容器来管理对象,并使用依赖注入来解决对象之间的依赖关系。

BeanFactory

在 Spring 中,BeanFactory 是一个很基础的容器,可以创建和管理对象。下面是一个示例:

<bean id="userDao" class="com.example.dao.UserDaoImpl"/>

<bean id="userService" class="com.example.service.UserService">
    <property name="userDao" ref="userDao"/>
</bean>

在这个示例中,我们创建了一个 UserDao 对象,并将其注入到 UserService 中。UserService 中的 userDao 属性使用 “property” 元素来注入,其中 “name” 表示属性名,ref=”userDao” 表示注入 userDao bean。

ApplicationContext

ApplicationContext 是一个更高级的容器,除了 BeanFactory 的所有功能外,还提供了更加方便的集成功能,例如国际化、事件处理、资源加载等。下面是一个示例:

<bean id="userDao" class="com.example.dao.UserDaoImpl"/>

<bean id="userService" class="com.example.service.UserService"/>

在这个示例中,我们创建了一个 UserDao 对象,和一个 UserService 对象。注意,这里并没有显式地指定 UserDao 对象的注入方式,Spring 会自动检测 UserService 中的需要注入的属性,并自动注入相应的对象。

示例1:构建一个基础的 Spring 应用

接下来,我们将演示如何使用 Spring 的依赖注入和控制反转功能,构建一个简单的 Spring 应用程序。

步骤

首先,创建一个基础的 Spring 应用程序,包含以下文件和类:

  1. pom.xml:用于管理项目依赖。
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.9.RELEASE</version>
    </dependency>
</dependencies>
  1. UserDao.java:创建一个 UserDao 接口。
public interface UserDao {
    void save();
}
  1. UserDaoImpl.java:创建 UserDao 的实现类。
public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("UserDaoImpl save method called");
    }
}
  1. UserService.java:创建 UserService 接口。
public interface UserService {
    void register();
}
  1. UserServiceImpl.java:创建 UserService 的实现类,并在其属性中注入 UserDao。
public class UserServiceImpl implements UserService {

    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void register() {
        userDao.save();
        System.out.println("UserServiceImpl register method called");
    }
}
  1. applicationContext.xml:配置 Spring 容器。
<bean id="userDao" class="com.example.dao.UserDaoImpl"/>

<bean id="userService" class="com.example.service.UserServiceImpl">
    <property name="userDao" ref="userDao"/>
</bean>
  1. Main.java:创建主函数用于测试应用程序。
public class Main {
    public static void main(String[] args) {
        // 加载配置文件
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 获取 UserService 实例
        UserService userService = context.getBean(UserService.class);
        // 调用 register 方法
        userService.register();
        // 关闭 Spring 容器
        context.close();
    }
}

实现过程

  1. 在 UserDao.java 中,我们创建了 UserDao 接口,其中定义了一个 save() 方法。

  2. 在 UserDaoImpl.java 中,我们创建了 UserDao 的实现类,并实现了 save() 方法。这个方法只是简单的打印一条消息,表示方法被调用了。

  3. 在 UserService.java 中,我们创建了 UserService 接口,并定义了一个 register() 方法。

  4. 在 UserServiceImpl.java 中,我们创建了 UserService 的实现类,并在其属性 userDao 中注入 UserDao 对象。在 register() 方法中,我们调用了 userDao 的 save() 方法,并打印了一条消息表示方法被调用了。

  5. 在 applicationContext.xml 中,我们配置了 Spring 容器,一共定义了两个 bean:userDao 和 userService。userService 中的 userDao 属性通过注入方式来实现。

  6. 在 Main.java 中,我们创建了主函数用于测试应用程序。我们加载了 applicationContext.xml 配置文件,并通过 context.getBean() 方法获取 UserService 实例。最后,调用 register() 方法,并关闭 Spring 容器。

到此为止,我们就完成了一个使用 Spring 的依赖注入和控制反转功能的简单应用程序。在运行程序时,我们可以看到控制台输出:

UserDaoImpl save method called
UserServiceImpl register method called

示例2:在 Spring Boot 应用程序中使用依赖注入

在 Spring Boot 应用程序中,Spring 自动配置了很多对象来简化我们的开发,我们只需要添加相关依赖,并在代码中注入相应的对象即可。

在这个示例中,我们将演示如何在 Spring Boot 应用程序中使用依赖注入。

步骤

首先,创建一个 Spring Boot 应用程序,包含以下文件和类:

  1. pom.xml:用于管理项目依赖。
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.1.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <version>2.1.4.RELEASE</version>
        <scope>test</scope>
    </dependency>
</dependencies>
  1. UserDao.java:创建一个 UserDao 接口。
public interface UserDao {
    void save();
}
  1. UserDaoImpl.java:创建 UserDao 的实现类。
@Repository
public class UserDaoImpl implements UserDao {

    public void save() {
        System.out.println("UserDaoImpl save method called");
    }
}
  1. UserService.java:创建 UserService 接口。
public interface UserService {
    void register();
}
  1. UserServiceImpl.java:创建 UserService 的实现类,并使用 @Autowired 注解对 UserDao 进行注入。
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    public void register() {
        userDao.save();
        System.out.println("UserServiceImpl register method called");
    }
}
  1. Main.java:创建主函数用于测试应用程序。
@RestController
public class Main {

    @Autowired
    UserService userService;

    @RequestMapping("/register")
    public String register() {
        userService.register();
        return "success";
    }

    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}

实现过程

  1. 在 UserDao.java 中,我们创建了 UserDao 接口,其中定义了一个 save() 方法。

  2. 在 UserDaoImpl.java 中,我们创建了 UserDao 的实现类,并使用 @Repository 注解将它声明为一个 bean。这个类中也实现了 save() 方法。

  3. 在 UserService.java 中,我们创建了 UserService 接口,并定义了一个 register() 方法。

  4. 在 UserServiceImpl.java 中,我们创建了 UserService 的实现类。这个类中使用 @Service 注解将其声明为一个 bean,并在 userDao 属性上使用 @Autowired 注解来进行注入。在 register() 方法中,我们调用了 userDao 的 save() 方法,并打印了一条消息表示方法被调用了。

  5. 在 Main.java 中,我们创建了主函数,并使用 @RestController 注解将其声明为一个 web 服务。在这个类中,我们将 UserService 注入到 userService 属性中,并编写了一个 /register 的接口用于测试服务。这个接口调用了 userService 的 register() 方法。

通过运行应用程序,我们可以在控制台上看到应用已经启动了。打开浏览器,输入 http://localhost:8080/register ,我们可以看到该接口调用了 UserServiceImpl 中的 register() 方法,并打印了一条消息表示方法被调用了。

至此,我们已经完成了如何在 Spring 应用程序和 Spring Boot 应用程序中使用依赖注入和控制反转的介绍。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入浅出讲解Spring框架中依赖注入与控制反转及应用 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • Java Cmd运行Jar出现乱码的解决方案

    请看以下完整攻略: Java Cmd运行Jar出现乱码的解决方案 很多Java程序员在用cmd运行jar包时,都会遇到乱码的问题。这主要是因为cmd默认编码是GBK而不是UTF-8,而jar包中的资源文件往往是UTF-8编码的。本文就为大家介绍几种解决方案。 方案一:修改Cmd编码为UTF-8 这种方式比较简单,只需要在cmd输入以下命令: chcp 650…

    Java 2023年5月20日
    00
  • Spring Aware源码设计示例解析

    让我们来详细讲解一下“Spring Aware源码设计示例解析”的攻略。 简介 在Spring中,我们经常使用Aware接口,例如BeanNameAware、ApplicationContextAware等,用来获得Spring ApplicationContext中的一些特定的信息。本文将对这些Aware接口的实现进行源码分析,并为读者提供一些示例,帮助读…

    Java 2023年5月31日
    00
  • 做java这么久了居然还不知道JSON的使用(一文带你了解)

    做java这么久了居然还不知道JSON的使用(一文带你了解) 前言 JSON是一种轻量级的数据交换格式,自从2006年被Douglas Crockford发明之后,它已经成为现代互联网应用程序中最流行的数据格式之一。在Java应用程序中,我们可以使用各种JSON库来处理JSON数据。 什么是JSON? JSON(JavaScript Object Notat…

    Java 2023年6月15日
    00
  • 一篇文章弄懂JVM类加载机制过程以及原理

    那么让我们来详细讲解一下“一篇文章弄懂JVM类加载机制过程以及原理”的完整攻略。 1. JVM类加载机制基础 在深入了解JVM类加载机制的过程之前,我们需要先了解一些相关的基础知识。 1.1 类、类加载器和类加载 在Java中,我们通常所说的类是指Java类,而Java类的定义是以.java文件为载体,通过编译器(如javac)将其转换为.class文件后生…

    Java 2023年5月26日
    00
  • 详解Spring Security的formLogin登录认证模式

    详解Spring Security的formLogin登录认证模式 概述 在使用Spring Security开发Web应用的过程中,我们通常需要用户进行身份验证和授权,而Spring Security的formLogin登录认证模式就是其中一种。formLogin认证模式是指用户将会通过一个用户名和密码的表单来进行身份验证。这个过程中,用户在浏览器中访问了…

    Java 2023年5月20日
    00
  • springAop实现权限管理数据校验操作日志的场景分析

    下面是关于“springAop实现权限管理数据校验操作日志的场景分析”的完整攻略,包含两个示例说明。 springAop实现权限管理数据校验操作日志的场景分析 Spring AOP(Aspect Oriented Programming)是一种面向切面编程的技术,它可以在不修改原有代码的情况下,对系统进行横向切割,实现诸如权限管理、数据校验、操作日志等功能。…

    Java 2023年5月17日
    00
  • 使用Log4j为项目配置日志输出应用详解以及示例演示的实现分析

    使用Log4j为项目配置日志输出应用详解以及实现分析 介绍 日志是软件开发中不可或缺的一个环节,能够对应用运行过程进行记录、分析和监控。Apache Log4j是Java中一个常用的日志框架,可以灵活地进行配置和使用。本攻略将对Log4j的使用进行详细讲解,并提供两个示例实现演示。 Log4j的配置 在项目中使用Log4j需要进行相关配置,一般包括三个方面:…

    Java 2023年5月26日
    00
  • javaweb图书商城设计之订单模块(5)

    “javaweb图书商城设计之订单模块(5)”是讲解Java Web技术在图书商城的订单模块中的实际应用的文章。下面是完整攻略: 1. 了解订单模块的作用 订单模块是通过电子商务网站完成用户向商家购书的过程中对购买物品的确认、支付以及收货、退货等交易活动的模块。订单模块是整个网站的核心功能,好的订单管理可提供对整个业务环节的监管和管理,降低运营成本。 2. …

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部