【Spring】认识 IoC 容器和 Servlet 容器

1.认识容器

1.1 IoC 容器

loC(Inversion of Control)容器,是面向对象编程中的一种设计原则,意为 控制反转(也被称为 控制反向控制倒置)。它将程序中创建对象的控制权交给 Spring 框架来管理,以便降低计算机代码之间的耦合度。

控制反转的实质是 获得依赖对象的过程 被反转了。这个过程由自身管理变为由 loC 容器主动注入。这正是 loC 实现的方式之一:依赖注入dependency injectionDI),由 loC 容器在运行期间动态地将某种依赖关系注入对象之中。

在传统编程方式中,要实现某种功能一般都需要几个对象相互作用。在主对象中要保存其他类型对象的引用,以便在主对象中实例化对象,然后通过调用这些引用的方法来完成任务,其运行方式如下图所示。
在这里插入图片描述
而 IoC 容器是在主对象中设置 Setter 方法,通过调用 Setter 方法或构造方法传入所需引用(即依赖注入),如下图所示。
在这里插入图片描述
要使用某个对象,只需要从 IoC 容器中获取需要使用的对象,不需要关心对象的创建过程,即把创建对象的控制权反转给了 Spring 框架。

1.2 loC 的实现方法

loC 的实现方法主要有两种:依赖注入依赖查找

1.2.1 依赖注入

在软件设计中,依赖 指的是一个类需要调用的其他类或者服务,而 注入 则是指将这些所需的类或服务传递给需要它们的类的过程。使用 依赖注入 技术,我们可以在运行时将依赖关系传递给对象,而不是让对象自己去创建或查找它们需要的依赖。

如此,则软件中的组件可以在不同环境下重复使用,就像家里的电器可以随意在不同的插座上使用一样,不用担心它们的电源问题。依赖注入 让我们的代码更加灵活,更容易维护和扩展。

在这里插入图片描述

loC 容器通过类型或名称等信息将不同对象注入不同属性中。组件不做定位查询,只提供普通的 Java 方法让容器去决定依赖关系。这是最流行的 loC 方法。依赖注入主要有以下几种方式。

  • 设值注入setter injection):让 loC 容器调用注入所依赖类型的对象。
  • 接口注入interface injection):实现特定接口,以供 loC 容器注入所依赖类型的对象。
  • 构造注入constructor injection):实现特定参数的构造函数,在创建对象时让 loC 容器注入所依赖类型的对象。
  • 基于注解:通过 Java 的注解机制让 loC 容器注入所依赖类型的对象,例如,使用 @Autowired。

loC 是通过第三方容器来管理并维护这些被依赖对象的,应用程序只需要接收并使用 IoC 容器注入的对象。

1.2.2 依赖查找

在传统实现中,需要用户使用 API 来管理依赖的创建、查找资源和组装对象。这会对程序有侵入性。

依赖查找 则通过调用容器提供的 回调接口上下文环境 来获取对象,在获取时需要提供相关的配置文件路径、key 等信息来确定获取对象的状态。依赖查找通常有两个方法:依赖拖拽DP)和 上下文依赖查找CDL)。

1.3 认识 Servlet 容器

Servlet 是在 javax.servlet 包中定义的一个接口。在开发 Spring Boot 应用程序时,使用 Controller 基本能解决大部分的功能需求。但有时也需要使用 Servlet,比如实现 拦截监听 功能。Spring Boot 的核心控制器 DispatcherServlet 会处理所有的请求。如果自定义 Servlet,则需要进行注册,以便 DispatcherServlet 核心控制器知道它的作用,以及处理请求 url-pattern

2.用 IoC 管理 Bean

2.1 创建一个 Bean

创建一个名为 User 的 Bean。

@Data
public class User implements Serializable {
    private int id;
    private String name;
    }

2.2 编写 User 的配置类

编写配置类,并实例化一个对象。

@Configuration
public class UserConfig {
    //将此返回的值生成一个bean
    @Bean("user1")
    public User user() {
        User user = new User();
        user.setId(1);
        user.setName("pipi");
        return user;
    }
}
  • @Confguration:用于标注配置类,让 Spring 来加载该类配置作为 Bean 的载体。在运行时,将为这些 Bean 生成 BeanDefinition 和服务请求。
  • @Bean:产生一个 Bean,并交给 Spring 管理。目的是封装用户、数据库中的数据,一般有 Setter、Getter 方法。

2.3 编写测试类

下面实例化一个 User 对象,然后通过上下文获取 Bean 对象 user1

@RunWith(SpringRunner.class)
@SpringBootTest
public class IocTest {
    @Autowired
    private ApplicationContext applicationContext;
    @Test
    public void testIoc() {
        User user = (User) applicationContext.getBean("user1");
        System.out.println(user);
    }
}
  • @RunWith(SpringRunner.class):让测试运行于 Spring 测试环境。
  • @SpringBootTest:Spring Boot 用于测试的注解,可指定入口类或测试环境等。
  • @Test:一个测试方法。
  • ApplicationContext:获取 Spring 容器中已初始化的 Bean,这里是 user1

运行 testIoC 方法,在控制台输出以下结果:

在这里插入图片描述

3.用 Servlet 处理请求

使用 Servlet 处理请求,可以直接通过注解 @WebServlet(urlPattern,descript) 注册 Servlet,然后在入口类中添加注解@ServletComponentScan,以扫描该注解指定包下的所有 Servlet。

3.1 注册 Servlet 类

package com.example.demo;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Description: 添加注解进行修饰
 */
@WebServlet(urlPatterns = "/ServletDemo02/*")
public class ServletDemo02 extends HttpServlet{
    /**
     * Description:
     * 重写doGet方法,父类的HttpServlet的doGet方法是空的,没有实现任何代码,子类需要重写此方法。
     *客户使用GET方式请求Servlet时,Web容器调用doGet方法处理请求。
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet");
        resp.getWriter().print("Servlet ServletDemo02");
    }
}
  • @WebServlet(urlPatterns = “/ServletDemo02/*”):属性 urlPatterns 指定 WebServlet 的作用范围,这里代表 ServletDemo02 下的所有子路径。
  • doGet:父类 HttpServlet 的 doGet 方法是空的,没有实现任何代码,子类需要重写此方法。

3.2 开启 Servlet 支持

在入口类上添加注解 @ServletComponentScan,以使 Servlet 生效。

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;

@ServletComponentScan
@SpringBootApplication
public class ServletDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServletDemoApplication.class, args);
    }
}
  • @ServletComponentScan:组件扫描,可自动发现和装配一些 Bean,并根据定义的扫描路径构符合扫描规则的类装配到 Spring 容器中。
  • @SpringBootApplication:入口类 Application 的启动注解。

在运行程序后,使用 GET 方法访问 http://localhost:8080/ServletDemo02/*,会返回重写 doGET 方法的值:

在这里插入图片描述
同时,控制台会输出 doGet 里定义的值:

在这里插入图片描述

  • 25
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

G皮T

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值