springBoot自动装配原理探究springBoot配置类Thymeleaf模板引擎
创始人
2024-05-27 07:01:05
0

微服务

微服务是一种架构风格,由于单体架构不利于团队协作完成并且代码量较大,后期维护成本较高,逐渐有了微服务架构。微服务是将一个项目拆分成不同的服务,各个服务之间相互独立互不影响,互相通过轻量级机制通信比如http通信。各个服务模块可以看成是一个单独的项目,可以由不同的编程语言,不同的数据存储技术进行开发,从而有效的实现“松耦合”。**微服务的目的就在于拆分应用、模块独立开发和部署。**相比于单体架构,微服务最大的优势就是实现了拆分应用、统一管理。

什么是springBoot

SpringBoot是一款基于Spring的快速开发框架,使用springBoot可以快速开发spring应用

springBoot为了简化使用ssm的大量复杂的配置文件,因此它内置了大量的市面主流组件,而任何一个springBoot内置的组件都对应有一个配置类。比如模板引擎thymeleaf对应的配置类ThymeleafProperties。并且我们依然可以在此基础上继续扩展或者进行其他配置,可以通过application.yml或者application.properties进行配置

SpringBoot内部集成了TomCat,不需要额外的配置,启动主程序即可运行

搭建SpringBoot

Spring内置了大量的第三方组件供我们使用,我们不再需要单独的去导入这些组件的依赖,这些组件都位于spring-boot-starter-xxx中可以理解为是一个启动器。并且spring也提供了这些组件的各个参数,来实现自定义组件开发,spring会根据我们的配置文件以及所导入的启动器来进行自动装配,自动装配是spring的核心所在
自动装配基于启动器,启动器配置依赖在Pom.xml文件中,比如

org.springframework.bootspring-boot-starter

将需要使用的依赖项配置即可,官网示例

在这里插入图片描述

下面是spring提供的主程序,也就是整个项目的入口。因为spring已经内置了一些服务器组件比如tomcat,我们从主程序启动就会由spring来完成服务器的项目部署以及运行。

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

spring自动装配原理

@SpringBootApplication注解,其中包含

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
// 上述四个是定义注解需要  核心注解是下面三个
@SpringBootConfiguration  // SpringBoot配置
@EnableAutoConfiguration  //  自动配置
@ComponentScan(   // 扫描包excludeFilters = {@Filter(type = FilterType.CUSTOM,classes = {TypeExcludeFilter.class}), @Filter(type = FilterType.CUSTOM,classes = {AutoConfigurationExcludeFilter.class})}
)

可以看到@SpringBootApplication是一个符合注解,也就是说如果直接定义@SprngBootConfiguration、@EnableAutoConfiguration、@ComponentScan三个注解也可以启动项目

@SpringBootConfigUration的内部其实是一个@Configuration注解,其作用就是将该注解所修饰的当前类作为配置类并且交给Spring容器托管,那么spring在扫描配置时便会扫描到该类,配置即可生效

@ComponentScan扫描包,相当于在spring的application-context.xml文件中去配置了conext:component-scan,如果不配置路径就会扫描当前所在包及其子包中的所有注解。目的就是让@Controller、@Service等注解生效

@EnableAutoConfiguration是实现自动装配的关键,它包含两个注解分别是@Import和@AutoConfigurationPackage
@Import引入了一个类AutoConfigurationImportSelector.class
该类是完成自动装配的重点:

  1. 先看该类下的selectImports方法,
public String[] selectImports(AnnotationMetadata annotationMetadata) {// 判断注解的数据是否存在if (!this.isEnabled(annotationMetadata)) {// 没有数据九返回  No-IMPORTS一个空的String数组return NO_IMPORTS;} else {// 否则将注解数据封装为自动配置的实体对象AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);return 
// 获取注解中的全部数据并转换成String数组  返回
StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}
}
  1. 点开封装注解数据的方法getAutoConfigurationEntry(annotationMetadata)

在这里插入图片描述

  1. getCandidateConfigurations方法:
protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {List configurations = new ArrayList(SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()));ImportCandidates.load(AutoConfiguration.class, this.getBeanClassLoader()).forEach(configurations::add);Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories nor in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you are using a custom packaging, make sure that file is correct.");return configurations;
}

可以发现当中给出了错误提示:根据@EnableConfiguration的全限定名去META-INF/spring.factories文件中获取我们需要导入的类,
@EnableConfiguration全限定名为:

org.springframework.boot.autoconfigure.EnableAutoConfiguration

最终会找到文件spring.factories,也就是大量需要自动装配的类

在这里插入图片描述
@AutoConfigurationPackage就是将主程序所在的包作为自动配置的包,spring默认会扫描本包及子包下的注解

@ConfigurationProperties注解可以将该配置类中的每一个属性值映射到yml文件当中进行绑定 该注解提供prefix字段用于指定yml同名的属性,我们可以使用该注解指定配置类

松散绑定:yml中的属性字段可以使用-进行风格,则其对应配置类中的属性就是连接-前后的字段并改为驼峰命名的属性。
例如:yml文件中:student-count对应student类中的studentCount属性,与mybatis中的驼峰命名映射类似

yml语法:

# 以key-value形式存储  key不能重复
server:
port: 8081
# 对象 行内写法
student: { name: yuqu,age: 13 }
# 对象
student2:
name: yuqu
age: 13
# 数组
students:
- 张三
- 李四
- 王五

进行配置时,你可以使用@Value注解直接为某字段赋值,也可以使用properties文件进行赋值,但是两者都没有yml更加灵活

JSR303校验

@Validatad数据校验注解,放在配置类的声明上,放置后则可以在该类下的字段上进行其他具体的校验配置,比如邮箱@Email()则该字段必须符合邮箱格式,否则报错,记得要添加JSR303校验的启动器,就是依赖


org.springframework.bootspring-boot-starter-validation

@Validated
public class Person {@Email()private String name;

常用HSR303注解

空检查@Null       验证对象是否为null@NotNull    验证对象是否不为null, 无法查检长度为0的字符串@NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.@NotEmpty 检查约束元素是否为NULL或者是EMPTY.Booelan检查@AssertTrue     验证 Boolean 对象是否为 true  @AssertFalse    验证 Boolean 对象是否为 false  长度检查@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内  @Length(min=, max=) Validates that the annotated string is between min and max included.日期检查@Past           验证 Date 和 Calendar 对象是否在当前时间之前  @Future     	验证 Date 和 Calendar 对象是否在当前时间之后  @Pattern    	验证 String 对象是否符合正则表达式的规则数值检查,建议使用在Stirng,Integer类型,不建议使用在int类型上,因为表单值为“”时无法转换为int,但可以转换为Stirng为"",Integer为null@Min            验证 Number 和 String 对象是否大等于指定的值  @Max            验证 Number 和 String 对象是否小等于指定的值  @DecimalMax 被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度@DecimalMin 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度@Digits     验证 Number 和 String 的构成是否合法  @Digits(integer=,fraction=) 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。@Range(min=, max=) 检查数字是否介于min和max之间.@Range(min=10000,max=50000,message="range.bean.wage")private BigDecimal wage;@Valid  递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证)@CreditCardNumber 信用卡验证@Email  验证是否是邮件地址,如果为null,不进行验证,算通过验证。@ScriptAssert(lang= ,script=, alias=)@URL(protocol=,host=, port=,regexp=, flags=)

SpringBoot核心:自动配置

导入静态资源

  1. 可以使用下面方式处理静态资源

    1. webjars
    2. public
    3. static
    4. /* *
    5. resource
  2. 这些是spring规定的默认扫描静态资源的位置,优先级为

    static > public > resource

在这里插入图片描述

定制首页:

默认情况下spring会在静态资源中寻找名叫index.html的页面作为首页
在templates下面的所有页面只能通过controller进行跳转,但需要模板引擎的支持

thymeleaf模板引擎

导入依赖


org.thymeleafthymeleaf-spring5

org.thymeleaf.extrasthymeleaf-extras-java8time

之前在使用springmvc开发时,依然是使用jsp视图与后端进行数据交互。但是spring并不推崇使用jsp,因为jsp的前后端耦合性过高。spring推荐使用html,只负责前端视图的展示,而数据交互就使用模板引擎比如上面提到的thymeleaf。简单来说就是之前我们使用servlet+jsp 换成了现在的servlet+thymeleaf+html

  1. 所有的模板引擎卸载templates包下
  2. 必须是以.html后缀结尾
  3. 引入命名空间:

示例:

@Controller
// 自动交由thymeleaf解析,并跳转至templates下的hello页面
// 注意如果没有配置thymeleaf依赖是无法跳转的
public class controller {@RequestMapping(value = "/hello")public String hello(){return "hello";}
}

由此,我们不需要再去配置springmvc的视图解析器并配置指定包下的.jsp文件后缀,全部交由模板引擎thymeleaf可以正常完成跳转

一些常用的thymeleaf语法:


th:text="${#dates.format(emp.getBirth(),'yyyy-MM-dd HH:mm:ss')}" th:href="@{/delete/}+${emp.getId()}" th:οnclick="update([[${emp.getId()}]])"

fragment抽取公共页面

在需要抽离的html中的最大标签定义th:fragment="sidebar",名称可以自定义,在需要引入的地方插入th:insert="~{dashboard::sidebar}",对应dashboard就是页面名称,后边为自定义字段

自动配置SpringMVC

自动转换器:前端提交的数据,经自动转换器自动封装为后台接收的对象
视图解析器、静态资源支持等等这些是SpringBoot已经内置好的springmvc的特性,我们依然可以通过手动去继续扩展其他配置比如拦截器、格式化器等等

自定义配置类,实现WebMvcConfigurer接口,利用@Configuration注解修饰,而且不能标注@EnableWebMvc。以自定义视图解析器DispatcherServlet为例:

@Configuration
public class MyConfig implements WebMvcConfigurer {public static class MyViewResolver implements ViewResolver{@Overridepublic View resolveViewName(String viewName, Locale locale) throws Exception {return null;}}@Beanpublic ViewResolver myViewResolver(){return new MyViewResolver();}
}

排错关于静态资源加载

针对thymeleaf加载静态资源时出现No mapping for GET /css/bootstrap.min.css等一系列资源找不到的问题,原因是利用@EnableWebMvc注解修饰了配置类,导致springBoot无法根据默认的静态资源位置进行扫描所以找不到。解决方法两种:

  1. 取出@EnableWebMvc注解
  2. 实现WebMvcConfigurer接口之后重新定义CLASSPATH_RESOURCE_LOCATIONS静态资源路径和资源处理器,如下
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {"classpath:/META-INF/resources/", "classpath:/resources/","classpath:/static/", "classpath:/public/" };// 资源处理
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {if (!registry.hasMappingForPattern("/webjars/**")) {registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");}if (!registry.hasMappingForPattern("/**")) {registry.addResourceHandler("/**").addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS);}

国际化消息转换LocaleResolver(区域设置解析)

配置i18n文件:在这里插入图片描述在这里插入图片描述

分别对应英文和中文,配置完成后修改前端界面的具体字段,以“请 登 录”为例:

Please sign in

也可以继续进行扩展,利用a标签实现点击切换中英文对照,如下:

中文
English

配置地区分解组件,并将其注入到配置类中托管给spring

// 地区分解  视图中英文调换
public class MyLocaleResolve implements LocaleResolver {// 解析请求@Overridepublic Locale resolveLocale(HttpServletRequest request) {// 获取请求的语言参数String lang = request.getParameter("lang");System.out.println("获取到视图传回的lang="+lang);// 默认语言参数Locale locale = Locale.getDefault();if (!StringUtils.isEmpty(lang)){// 不为空  使用请求的语言String[] s = lang.split("_");locale = new Locale(s[0], s[1]);}return locale;}@Overridepublic void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {}
}

注入@Configuration配置类中

// 自定义地区分解组件注入  生效
@Bean
public LocaleResolver localeResolver(){return new MyLocaleResolve();
}

yml配置:

spring:# 关闭thymeleaf缓存thymeleaf:cache: false# 配置中英转换messages:basename: i18n.login

拦截器

设置未登录用户权限,拦截请求

  1. 自定义登录拦截器 LoginHandlerInterceptor实现HandlerInterceptor接口并重写preHandle方法,根据用户是否登录和请求url进行判断,
// 登录拦截器
public class LoginHandlerInterceptor implements HandlerInterceptor {// 配置拦截器 请求拦截@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 查看当前用户是否已经登录Object currentUser = request.getSession().getAttribute("currentUser");if (currentUser==null){request.setAttribute("message","没有权限,请先登录!");// 没有登录返回登陆界面request.getRequestDispatcher("/index.html").forward(request,response);return false;}else {return true;}}
}
  1. 向配置类中注入自定义的拦截器
// 注入自定义拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
.excludePathPatterns("/index.html","/","/user/login","/css/*","/js/*","/img/*");
}

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...