JavaWeb--20 SpringBoot原理

1 配置优先级

在SpringBoot项目当中,常见的属性配置方式有5种, 3种配置文件,加上2种外部属性的配置(Java系统属性、命令行参数)。我们得出了优先级(从低到高):

  • application.yaml(忽略)
  • application.yml
  • application.properties
  • java系统属性(-Dxxx=xxx)
  • 命令行参数(–xxx=xxx)

配置文件优先级排名(从低到高):

  1. yaml配置文件
  2. yml配置文件
  3. properties配置文件

2 Bean管理

我们可以通过Spring当中提供的注解@Component以及它的三个衍生注解(@Controller、@Service、@Repository)来声明IOC容器中的bean对象。

我们今天主要学习IOC容器中Bean的其他使用细节,主要学习以下三方面:

  1. 如何从IOC容器中手动的获取到bean对象
  2. bean的作用域配置
  3. 管理第三方的bean对象

2.1 获取Bean

默认情况下,SpringBoot项目在启动的时候会自动的创建IOC容器(也称为Spring容器),并且在启动的过程当中会自动的将bean对象都创建好,存放在IOC容器当中。应用程序在运行时需要依赖什么bean对象,就直接进行依赖注入就可以了。

而在Spring容器中提供了一些方法,可以主动从IOC容器中获取到bean对象,下面介绍3种常用方式:

  1. 根据name获取bean
Object getBean(String name)
  1. 根据类型获取bean
<T> T getBean(Class<T> requiredType)
  1. 根据name获取bean(带类型转换)
<T> T getBean(String name, Class<T> requiredType)

思考:要从IOC容器当中来获取到bean对象,需要先拿到IOC容器对象,怎么样才能拿到IOC容器呢?

  • 想获取到IOC容器,直接将IOC容器对象注入进来就可以了

例如:
业务实现类:DeptServiceImpl

@Slf4j
@Service
public class DeptServiceImpl implements DeptService {
    @Autowired
    private DeptMapper deptMapper;

    @Override
    public List<Dept> list() {
        List<Dept> deptList = deptMapper.list();
        return deptList;
    }

    @Override
    public void delete(Integer id) {
        deptMapper.delete(id);
    }
}

输出的bean对象地址值是一样的,说明IOC容器当中的bean对象有几个?

答案:只有一个。 (默认情况下,IOC中的bean对象是单例)

那么能不能将bean对象设置为非单例的(每次获取的bean都是一个新对象)?

可以,在下一个知识点(bean作用域)中讲解。

2.2 Bean作用域

在前面我们提到的IOC容器当中,默认bean对象是单例模式(只有一个实例对象)。那么如何设置bean对象为非单例呢?需要设置bean的作用域。

在Spring中支持五种作用域,后三种在web环境才生效:

作用域说明
singleton容器内同名称的bean只有一个实例(单例)(默认)
prototype每次使用该bean时会创建新的实例(非单例)
request每个请求范围内会创建新的实例(web环境中,了解)
session每个会话范围内会创建新的实例(web环境中,了解)
application每个应用范围内会创建新的实例(web环境中,了解)

知道了bean的5种作用域了,我们要怎么去设置一个bean的作用域呢?

  • 可以借助Spring中的@Scope注解来进行配置作用域
    在这里插入图片描述

2.3 第三方Bean

学习完bean的获取、bean的作用域之后,接下来我们再来学习第三方bean的配置。

之前我们所配置的bean,像controller、service,dao三层体系下编写的类,这些类都是我们在项目当中自己定义的类(自定义类)。当我们要声明这些bean,也非常简单,我们只需要在类上加上@Component以及它的这三个衍生注解(@Controller、@Service、@Repository),就可以来声明这个bean对象了。
但是在我们项目开发当中,还有一种情况就是这个类它不是我们自己编写的,而是我们引入的第三方依赖当中提供的。

        <!--Dom4j-->
        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>

@Component 及衍生注解 与 @Bean注解使用场景?
项目中自定义的,使用@Component及其衍生注解
项目中引入第三方的,使用@Bean注解

3 SpringBoot原理

Spring是目前世界上最流行的Java框架,它可以帮助我们更加快速、更加容易的来构建Java项目。而在Spring家族当中提供了很多优秀的框架,而所有的框架都是基于一个基础框架的SpringFramework(也就是Spring框架)。而前面我们也提到,如果我们直接基于Spring框架进行项目的开发,会比较繁琐。

这个繁琐主要体现在两个地方:

  1. 在pom.xml中依赖配置比较繁琐,在项目开发时,需要自己去找到对应的依赖,还需要找到依赖它所配套的依赖以及对应版本,否则就会出现版本冲突问题。
  2. 在使用Spring框架进行项目开发时,需要在Spring的配置文件中做大量的配置,这就造成Spring框架入门难度较大,学习成本较高。
    基于Spring存在的问题,官方在Spring框架4.0版本之后,又推出了一个全新的框架:SpringBoot。

通过 SpringBoot来简化Spring框架的开发(是简化不是替代)。我们直接基于SpringBoot来构建Java项目,会让我们的项目开发更加简单,更加快捷。

SpringBoot框架之所以使用起来更简单更快捷,是因为SpringBoot框架底层提供了两个非常重要的功能:一个是起步依赖,一个是自动配置。
通过SpringBoot所提供的起步依赖,就可以大大的简化pom文件当中依赖的配置,从而解决了Spring框架当中依赖配置繁琐的问题。

通过自动配置的功能就可以大大的简化框架在使用时bean的声明以及bean的配置。我们只需要引入程序开发时所需要的起步依赖,项目开发时所用到常见的配置都已经有了,我们直接使用就可以了。

3.1 起步依赖

假如我们没有使用SpringBoot,用的是Spring框架进行web程序的开发,此时我们就需要引入web程序开发所需要的一些依赖。

  • spring-webmvc依赖:这是Spring框架进行web程序开发所需要的依赖

  • servlet-api依赖:Servlet基础依赖

  • jackson-databind依赖:JSON处理工具包

  • 如果要使用AOP,还需要引入aop依赖、aspect依赖

  • 如果我们使用了SpringBoot,就不需要像上面这么繁琐的引入依赖了。我们只需要引入一个依赖就可以了,那就是web开发的起步依赖:springboot-starter-web。

起步依赖的原理就是Maven的依赖传递

3.2 自动配置

我们讲解了SpringBoot当中起步依赖的原理,就是Maven的依赖传递。接下来我们解析下自动配置的原理,我们要分析自动配置的原理,首先要知道什么是自动配置。

3.2.1 概述

SpringBoot的自动配置就是当Spring容器启动后,一些配置类、bean对象就自动存入到了IOC容器中,不需要我们手动去声明,从而简化了开发,省去了繁琐的配置操作。

比如:我们要进行事务管理、要进行AOP程序的开发,此时就不需要我们再去手动的声明这些bean对象了,我们直接使用就可以从而大大的简化程序的开发,省去了繁琐的配置操作。

方案一:@ComponentScan 组件扫描

@ComponentScan({"com.example","com.itheima"})
@SpringBootApplication
public class SpringbootWebConfig2Application {
}

方案二:@Import 导入。使用@Import导入的类会被Spring加载到IOC容器中,导入形式主要有以下几种:
导入 普通类
导入 配置类
导入 ImportSelector 接口实现类
@EnableXxxx注解,封装@Import注解

pom文件中加入配置项

        <!--itheima-utils-->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>itheima-utils</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
@Import({TokenParser.class, HeaderConfig.class})
@SpringBootApplication
public class SpringbootWebConfig2Application {
}

自动配置作用:
按照一定的条件进行判断,在满足给定条件后才会注册对应的bean对象到Spring IOC容器中。
位置:方法、类

  • @Conditional 本身是一个父注解,派生出大量的子注解:
  • @ConditionalOnClass:判断环境中是否有对应字节码文件,才注册bean到IOC容器。
  • @ConditionalOnMissingBean:判断环境中没有对应的bean(类型 或 名称) ,才注册bean到IOC容器。
  • @ConditionalOnProperty:判断配置文件中有对应属性和值,才注册bean到IOC容器。
@Bean
@ConditionalOnClass(name = "io.jsonwebtoken.Jwts") //当前环境存在指定的这个类时,才声明该bean 
public HeaderParser headerParser(){...}

@Bean
@ConditionalOnMissingBean //当不存在当前类型的bean时,才声明该bean 
public HeaderParser headerParser(){...}

@Bean
@ConditionalOnProperty(name = "name",havingValue = "itheima") 
//配置文件中存在对应的属性和值,才注册bean到IOC容器。
public HeaderParser headerParser(){...}

这一部分需要记的很多,建议看黑马Javaweb视频

4 Javaweb开发总结

web后端开发现在基本上都是基于标准的三层架构进行开发的,在三层架构当中,Controller控制器层负责接收请求响应数据,Service业务层负责具体的业务逻辑处理,而Dao数据访问层也叫持久层,就是用来处理数据访问操作的,来完成数据库当中数据的增删改查操作。
在这里插入图片描述
在三层架构当中,前端发起请求首先会到达Controller(不进行逻辑处理),然后Controller会直接调用Service 进行逻辑处理, Service再调用Dao完成数据访问操作。

如果我们在执行具体的业务处理之前,需要去做一些通用的业务处理,比如:我们要进行统一的登录校验,我们要进行统一的字符编码等这些操作时,我们就可以借助于Javaweb当中三大组件之一的过滤器Filter或者是Spring当中提供的拦截器Interceptor来实现。

在这里插入图片描述
而为了实现三层架构层与层之间的解耦,我们学习了Spring框架当中的第一大核心:IOC控制反转与DI依赖注入。

所谓控制反转,指的是将对象创建的控制权由应用程序自身交给外部容器,这个容器就是我们常说的IOC容器或Spring容器。

而DI依赖注入指的是容器为程序提供运行时所需要的资源。

除了IOC与DI我们还讲到了AOP面向切面编程,还有Spring中的事务管理、全局异常处理器,以及传递会话技术Cookie、Session以及新的会话跟踪解决方案JWT令牌,阿里云OSS对象存储服务,以及通过Mybatis持久层架构操作数据库等技术。

Filter过滤器、Cookie、 Session这些都是传统的JavaWeb提供的技术。

JWT令牌、阿里云OSS对象存储服务,是现在企业项目中常见的一些解决方案。

IOC控制反转、DI依赖注入、AOP面向切面编程、事务管理、全局异常处理、拦截器等,这些技术都是 Spring Framework框架当中提供的核心功能。

Mybatis就是一个持久层的框架,是用来操作数据库的。

### 回答1: Spring Boot的filter原理是在请求/响应处理链中对请求/响应进行拦截,进行相应的处理。Filter允许在Servlet请求处理链中插入代码以执行某些任务,例如:请求验证、请求记录、请求压缩等。每个Filter都实现javax.servlet.Filter接口,其中的doFilter方法提供了一个FilterChain对象,它允许在Filter处理请求后转移到下一个Filter或目标资源(如Servlet)。 通过配置Filter,可以在请求/响应处理链的任意位置插入新的处理逻辑,并且可以在应用程序的任意地方使用。因此,Filter是一种强大的工具,可以用来在不更改主要代码的情况下对请求/响应处理链进行扩展。 ### 回答2: Spring Boot的Filter原理是基于Servlet的Filter实现的。Filter是JavaWeb中的一种组件,用于在请求到达Servlet之前或响应返回给客户端前对请求和响应进行处理和拦截。 在Spring Boot中,可以通过配置@WebFilter注解或实现javax.servlet.Filter接口来定义一个Filter。当启动Spring Boot应用时,它会根据配置进行Filter的注册和初始化工作。Filter会对请求进行拦截,并可对请求进行修改或响应进行处理。 Filter在请求到达Servlet之前进行处理,可以对请求进行过滤、修改请求头或参数、校验权限等操作。在响应返回给客户端时,Filter也可以对响应进行处理,例如修改响应内容、添加响应头等。 不同的Filter可以形成一个Filter链,多个Filter可以按顺序对同一个请求进行处理。在Spring Boot中,Filter链的顺序可以通过注解配置或代码中的设置进行控制。 Spring Boot的Filter原理是基于Servlet容器的Filter链实现的,它提供了许多Filter,如CharacterEncodingFilter用于设置请求和响应的字符编码、CorsFilter用于处理跨域请求等。 Spring Boot还提供了许多扩展点和工具类,用于处理Filter相关的逻辑,例如注册和初始化Filter、控制Filter的顺序等。 总结而言,Spring Boot的Filter原理是通过Servlet容器的Filter链实现的,它可以拦截和处理请求、修改和处理响应,用于进行一些通用的处理,如权限校验、字符编码设置、跨域处理等。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值