认识Ioc容器和Servlet容器

1.介绍loC容器

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

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

在传统编程方式中,要实现某种功能一般都需要几个对象相互作用。在主对象中要保存其他类型对象的引用,以便在主对象中实例化对象,然后通过调用这些引用的方法来完成任务,其运行方式如图

而IoC容器是在主对象中设置Setter方法,通过调用Setter方法或构造方法传入所需引用(即 依赖注入),如图所示。

要使用某个对象,只需要从loC容器中获取需要使用的对象,不需要关心对象的创建过程,即 把创建对象的控制权反转给了 Spring框架。

2.loC的实现方法

IoC的实现方法主要有两种——依赖注入与依赖查找。

(1 )依赖注入。

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

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

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

(2)依赖查找。

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

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

3.认识Servlet容器

Servlet是在javax.serlvet包中定义的一个接口。在开发Spring Boot应用程序时,使用 Controller基本能解决大部分的功能需求。但有时也需要使用Servlet,比如实现拦截和监听功能。

Spring Boot的核心控制器DispatcherServlet会处理所有的请求。如果自定义Servlet,则需 要进行注册,以便DispatcherServlet核心控制器知道它的作用,以及处理请求url-pattern。

实例14:用loC管理Bean

1.创建一个Bean

package com.itheima.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private long id;
private String name;
private int age;
}

2.编写User的配置类

package com.itheima.config;
import com.itheima.domain.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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

3.编写测试类

package com.itheima;
import com.itheima.domain.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;

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

  User(id=55, name=Joe, age=65)

实例:用Servlet处理请求

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

1.注册Servlet类

package com.itheima.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.https.httpsServlet;
import javax.servlet.https.httpsServletRequest;
import javax.servlet.https.httpsServletResponse;
import java.io.IOException;

@WebServlet(urlPatterns = "/servlet/*")
public class ServletDemo extends httpsServlet {
@Override
protected void doGet(httpsServletRequest req, httpsServletResponse resp)throws ServletException, IOException{
System.out.println("DoGet");
resp.getWriter().print("ServletTest");
}
}

@WebServlet(urlPatterns = “/servlet/*“):属性 urlPatterns 指定 WebServlet 的作用范围,这里代表servlet下的所有子路径。

doGet:父类httpsServlet的doGet方法是空的,没有实现任何代码,子类需要重写此方法。

2.开启Servlet支持

package com.itheima;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@ServletComponentScan
@SpringBootApplication
public class Springboot05MybatisApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot05MybatisApplication.class, args);
}
}

@ComponentScan:组件扫描、可自动发现和装配一些Bean,并根据定义的扫描路径把 符合扫描规则的类装配到Spring容器中。

@SpringBootAppfication:入口类 Application 的启动注解。

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

ServletTest

同时,控制台会输出doGet里定义的值:

DoGet