关于SpringBoot:

特征:

  • 可以创建独立的Spring应用程序,并且基于其Maven或Gradle插件,可以创建可执行的JARs和WARs;
  • 内嵌Tomcat或Jetty等Servlet容器;
  • 提供自动配置的“starter”项目对象模型(POMS)以简化Maven配置;
  • 尽可能自动配置Spring容器;
  • 提供准备好的特性,如指标、健康检查和外部化配置;
  • 绝对没有代码生成,不需要XML配置。

两种设计策略:

开箱即用:在开发过程中,通过maven项目的pom文件中添加相关依赖包,然后通过相应的注解来代替繁琐的XML配置以管理对象的生命周期。

约定大于配置:由SpringBoot本身来配置目标结构,由开发者在结构中添加信息的软件设计范式。这一特点虽降低了部分灵活性,增加了BUG定位的复杂性,但减少了开发人员需要做出决定的数量,同时减少了大量的XML配置,并且可以将代码编译、测试和打包等工作自动化。

yaml

  • YAML 的语法和其他高级语言类似,并且可以简单表达清单、散列表,标量等数据形态。它使用空白符号缩进和大量依赖外观的特色,特别适合用来表达或编辑数据结构、各种配置文件、倾印调试内容、文件大纲。

基本语法

  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进不允许使用tab,只允许空格
  • 缩进的空格数不重要,只要相同层级的元素左对齐即可
  • ‘#’表示注释

数据类型

YAML 支持以下几种数据类型:

  • 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
  • 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
  • 纯量(scalars):单个的、不可再分的值

示例

  1. #对象
  2. key:
  3. child-key: value
  4. child-key2: value2
  5. #数组
  6. child-key3:
  7. - A
  8. - B
  9. boolean:
  10. - TRUE #true,True都可以
  11. - FALSE #false,False都可以
  12. float:
  13. - 3.14
  14. - 6.8523015e+5 #可以使用科学计数法
  15. int:
  16. - 123
  17. - 0b1010_0111_0100_1010_1110 #二进制表示
  18. null:
  19. nodeName: 'node'
  20. parent: ~ #使用~表示null
  21. string:
  22. - 哈哈
  23. - 'Hello world' #可以使用双引号或者单引号包裹特殊字符
  24. - newline
  25. newline2 #字符串可以拆成多行,每一行会被转化成一个空格
  26. date:
  27. - 2018-02-17 #日期必须使用ISO 8601格式,即yyyy-MM-dd
  28. datetime:
  29. - 2018-02-17T15:02:31+08:00 #时间使用ISO 8601格式,时间和日期之间使用T连接,最后使用+代表时区
  30. #& 锚点和 * 别名,可以用来引用:

yaml多模块多环境配置

  1. server:
  2. port: 8080
  3. #默认
  4. spring:
  5. profiles:
  6. active: dev
  7. #名字激活使用模块
  8. ---
  9. #分割模块
  10. server:
  11. port: 8081
  12. spring:
  13. profiles: dev
  14. #命名dev
  15. ---
  16. spring:
  17. profiles: test

pom.xml 说明

一、父依赖

  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <version>2.4.1</version>
  5. <relativePath/> <!-- lookup parent from repository -->
  6. </parent>
  • spring-boot-dependencies:作为父工程,存放了SpringBoot的核心依赖。我们在写或者引入一些SpringBoot依赖的时候,不需要指定版本,正是因为SpringBoot的父依赖已经帮我们维护了一套版本。

  • 另外在父依赖中也帮我们写好了资源库,不用我们自己再去配置了。

二、启动器

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter</artifactId>
  4. <version>2.2.1.RELEASE</version>
  5. </dependency>

启动器就是SpringBoot的启动场景,比如我们要使用web相关的,那么就直接引入spring-boor-starter-web,那么他就会帮我们自动导入web环境下所有必需的依赖。

其中存放了自动配置相关的依赖、日志相关依赖、还有Spring-core等依赖,这些依赖我们只需要导入一个spring-boor-starter就可以直接将其全部引入,而不需要再像以前那样逐个导入了。

SpringBoot会将所有的功能场景都封装成一个一个的启动器。

@ConfigurationProperties(prefix = “”)

  • 使用配置文件方法注入
  • 将配置文件中的每一个属性映射到这个组件中,Springboot将本类中的属性于配置文件中的配置一一对应,使用的前提是 这个组件是容器的组件

.yaml

  1. dog:
  2. name: huanghua
  3. age: 3

.java

  1. @Component
  2. @ConfigurationProperties(prefix = "dog")
  3. public class Dog {
  4. private String name;
  5. private Integer age;
  6. }

在使用该注解的时候会有一个爆红提示,添加依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-configuration-processor</artifactId>
  4. <optional>true</optional>
  5. </dependency>

测试类

  1. @SpringBootTest
  2. class DemoApplicationTests {
  3. @Autowired
  4. private Dog dog;
  5. @Test
  6. void contextLoads() {
  7. System.out.println(dog);
  8. }
  9. }

注意在需要使用注入的对象添加@Autowired 实现自动注入

SpringBoot 注解

1、@SpringBootApplication

这是 Spring Boot 最最最核心的注解,用在 Spring Boot 主类上,标识这是一个 Spring Boot 应用,用来开启 Spring Boot 的各项能力。

其实这个注解就是 @SpringBootConfiguration@EnableAutoConfiguration@ComponentScan 这三个注解的组合,也可以用这三个注解来代替 @SpringBootApplication 注解。

2、@EnableAutoConfiguration

允许 Spring Boot 自动配置注解,开启这个注解之后,Spring Boot 就能根据当前类路径下的包或者类来配置 Spring Bean。

如:当前类路径下有 Mybatis 这个 JAR 包,MybatisAutoConfiguration 注解就能根据相关参数来配置 Mybatis 的各个 Spring Bean。

3、@Configuration

这是 Spring 3.0 添加的一个注解,用来代替 applicationContext.xml 配置文件,所有这个配置文件里面能做到的事情都可以通过这个注解所在类来进行注册。

4、@SpringBootConfiguration

这个注解就是 @Configuration 注解的变体,只是用来修饰是 Spring Boot 配置而已,或者可利于 Spring Boot 后续的扩展。

5、@ComponentScan

这是 Spring 3.1 添加的一个注解,用来代替配置文件中的 component-scan 配置,开启组件扫描,即自动扫描包路径下的 @Component 注解进行注册 bean 实例到 context 中。

前面 5 个注解可以在Java技术栈的这篇文章《Spring Boot 最核心的 3 个注解详解》中了解更多细节的。

6、@Conditional

这是 Spring 4.0 添加的新注解,用来标识一个 Spring Bean 或者 Configuration 配置文件,当满足指定的条件才开启配置。

7、@ConditionalOnBean

组合 @Conditional 注解,当容器中有指定的 Bean 才开启配置。

8、@ConditionalOnMissingBean

组合 @Conditional 注解,和 @ConditionalOnBean 注解相反,当容器中没有指定的 Bean 才开启配置。

9、@ConditionalOnClass

组合 @Conditional 注解,当容器中有指定的 Class 才开启配置。

10、@ConditionalOnMissingClass

组合 @Conditional 注解,和 @ConditionalOnMissingClass 注解相反,当容器中没有指定的 Class 才开启配置。

11、@ConditionalOnWebApplication

组合 @Conditional 注解,当前项目类型是 WEB 项目才开启配置。

当前项目有以下 3 种类型。

  1. enum Type {
  2. /**
  3. * Any web application will match.
  4. */
  5. ANY,
  6. /**
  7. * Only servlet-based web application will match.
  8. */
  9. SERVLET,
  10. /**
  11. * Only reactive-based web application will match.
  12. */
  13. REACTIVE
  14. }

12、@ConditionalOnNotWebApplication

组合 @Conditional 注解,和 @ConditionalOnWebApplication 注解相反,当前项目类型不是 WEB 项目才开启配置。

13、@ConditionalOnProperty

组合 @Conditional 注解,当指定的属性有指定的值时才开启配置。

14、@ConditionalOnExpression

组合 @Conditional 注解,当 SpEL 表达式为 true 时才开启配置。

15、@ConditionalOnJava

组合 @Conditional 注解,当运行的 Java JVM 在指定的版本范围时才开启配置。

16、@ConditionalOnResource

组合 @Conditional 注解,当类路径下有指定的资源才开启配置。

17、@ConditionalOnJndi

组合 @Conditional 注解,当指定的 JNDI 存在时才开启配置。

18、@ConditionalOnCloudPlatform

组合 @Conditional 注解,当指定的云平台激活时才开启配置。

19、@ConditionalOnSingleCandidate

组合 @Conditional 注解,当指定的 class 在容器中只有一个 Bean,或者同时有多个但为首选时才开启配置。

20、@ConfigurationProperties

用来加载额外的配置(如 .properties 文件),可用在 @Configuration 注解类,或者 @Bean 注解方法上面。

关于这个注解的用法可以参考Java技术栈《 Spring Boot读取配置的几种方式》这篇文章。

21、@EnableConfigurationProperties

一般要配合 @ConfigurationProperties 注解使用,用来开启对 @ConfigurationProperties 注解配置 Bean 的支持。

22、@AutoConfigureAfter

用在自动配置类上面,表示该自动配置类需要在另外指定的自动配置类配置完之后。

如 Mybatis 的自动配置类,需要在数据源自动配置类之后。

  1. @AutoConfigureAfter(DataSourceAutoConfiguration.class)
  2. public class MybatisAutoConfiguration {

23、@AutoConfigureBefore

这个和 @AutoConfigureAfter 注解使用相反,表示该自动配置类需要在另外指定的自动配置类配置之前。

24、@Import

这是 Spring 3.0 添加的新注解,用来导入一个或者多个 @Configuration 注解修饰的类,这在 Spring Boot 里面应用很多。

25、@ImportResource

这是 Spring 3.0 添加的新注解,用来导入一个或者多个 Spring 配置文件,这对 Spring Boot 兼容老项目非常有用,因为有些配置无法通过 Java Config 的形式来配置就只能用这个注解来导入。

JSR303校验

@Validate 数据校验

依赖

  1. <dependency>
  2. <groupId>javax.validation</groupId>
  3. <artifactId>validation-api</artifactId>
  4. <version>1.1.0.Final</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.hibernate</groupId>
  8. <artifactId>hibernate-validator</artifactId>
  9. <version>5.4.1.Final</version>
  10. </dependency>

自动装配原理

  1. @SpringBootApplication:标注这个类是一个SpringBoot的启动类
  1. 进入@SpringBootApplication
  1. @SpringBootConfiguration
  2. @EnableAutoConfiguration
  • 进来之后我们发现主要有两个注解组成,这两个注解是整个SpringBoot 的核心
  1. @SpringBootConfiguration
  1. @Configuration
  • 进入@SpringBootConfiguration 之后发现@SpringBootConfiguration 里面就是一个@Configuration注解,所以可以理解为@SpringBootConfiguration = @Configuration
  1. @EnableAutoConfiguration
  1. @AutoConfigurationPackage //自动导入包
  2. @Import({AutoConfigurationImportSelector.class}) //自动配置导入选择
  • @EnableAutoConfiguration 顾名思义 “启用自动配置”
  • 下面主要是两个注解构成,分别代表自动导入包,自动配置导入选择
  • @Import({AutoConfigurationImportSelector.class}) 这个意思是导入AutoConfigurationImportSelector 这个类,这个类中有一个方法可以帮助我们获取所有的配置 如下:
  1. 查看 AutoConfigurationImportSelector
  1. List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
  • 所有配置以List 的形式都存放在configurations 里面,而这些配置都是从getCandidateConfigurations 中获取,getCandidateConfigurations ,这个方法是用来获取候选的配置
  1. getCandidateConfigurations
  1. protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
  2. List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
  3. Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
  4. return configurations;
  5. }
  • 进入到这个方法,看到了一串断言代码
  1. Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");

这个断言的意思就是,configurations 必须非空,否则的话就把后面的字符串打印出来,字符串里面的META-INF/spring.factories 就是自动配置的属性信息。

  1. 查看 META-INF/spring.factories
  • 根据目录找到META-INF/spring.factories文件

这个文件里面包含了很多的配置属性,诸如webMvcAutoConfiguration 等

  1. 结论
    当我们的SpringBoot项目启动的时候,会先导入AutoConfigurationImportSelector,这个类会帮我们选择所有候选的配置,我们需要导入的配置都是SpringBoot帮我们写好的一个一个的配置类,那么这些配置类的位置,存在与META-INF/spring.factories文件中,通过这个文件,Spring可以找到这些配置类的位置,于是去加载其中的配置。

  2. 注意
    以上配置文件在启动的时候并不是把它们全部加载的

  • (如上:) 打开配置属性中的随便一个类看到了两个注解
  1. @ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
  2. @ConditionalOnMissingBean({WebMvcConfigurationSupport.class})

这个注解的意思就是,检测相关类是否存在,假设这个类不存在这不会加载该配置文件

@ConditionalOnXXX:如果其中的条件都满足,该类才会生效。

所以在加载自动配置类的时候,并不是将spring.factories的配置全量加载进来,而是通过这个注解的判断,如果注解中的类都存在,才会进行加载。

所以就实现了:我们在pom.xml文件中加入stater启动器,SpringBoot自动进行配置。完成开箱即用。

得出过程:

(SpringBoot所有自动配置类都是在启动的时候进行扫描并加载,通过spring.factories可以找到自动配置类的路径,但是不是所有存在于spring,factories中的配置都进行加载,而是通过@ConditionalOnClass注解进行判断条件是否成立(只要导入相应的stater,条件就能成立),如果条件成立则加载配置类,否则不加载该配置类。)

  • SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值
  • 将这些值作为自动配置类导入容器 , 自动配置类就生效 , 帮我们进行自动配置工作;
  • 以前我们需要自己配置的东西 , 自动配置类都帮我们解决了
  • 整个J2EE的整体解决方案和自动配置都在springboot-autoconfigure的jar包中;
  • 它将所有需要导入的组件以全类名的方式返回 , 这些组件就会被添加到容器中 ;
  • 它会给容器中导入非常多的自动配置类 (xxxAutoConfiguration), 就是给容器中导入这个场景需要的所有组件 , 并配置好这些组件 ;
  • 有了自动配置类 , 免去了我们手动编写配置注入功能组件等的工作;

“约定” —- 配置文件

SpringBoot 规定了我们的配置文件(.yaml/yml/properties)应该放在哪个目录下,配置文件的命名,项目启动时扫描的Bean, 组件的默认配置是什么样的等 ”约定“。

  • Spring 官网规定了文档的目录结构

Config locations are searched in reverse order. By default, the configured locations are classpath:/,classpath:/config/,file:./,file:./config/. The resulting search order is the following:

  • file:./config/
  • file:./
  • classpath:/config/
  • classpath:/

意思就是Spring 的配置文件可以放在以下目录

/config

/(根目录)

resource/config/

resource/

这四个种路径优先级自上而下降低

  • SpringBoot可以加载一下三种配置文件

application.yml

application.yaml

application.properites

推荐使用前两种

  • 项目启动时包的扫描范围约定

SpringBoot的注解扫描的默认规则是SpringBoot的入口类所在包及其子包。

若入口类所在的包是cn.objectspace.demo那么自动扫描包的范围是cn.objectspace.demo包及其下面的子包,如果service包和dao包不在此范围,则不会自动扫描。

根据上面的解释以SpringMVC 的自动配置类为例得处装配原理

  1. @Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})
  2. @EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class, WebProperties.class})
  3. @Order(0)
  4. public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {
  5. private static final Log logger = LogFactory.getLog(WebMvcConfigurer.class);
  6. private final Resources resourceProperties;
  7. private final WebMvcProperties mvcProperties;
  8. private final ListableBeanFactory beanFactory;
  9. private final ObjectProvider<HttpMessageConverters> messageConvertersProvider;
  10. private final ObjectProvider<DispatcherServletPath> dispatcherServletPath;
  11. private final ObjectProvider<ServletRegistrationBean<?>> servletRegistrations;
  12. final WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer;
  13. public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebProperties webProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider, ObjectProvider<WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider, ObjectProvider<DispatcherServletPath> dispatcherServletPath, ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
  14. this.resourceProperties = (Resources)(resourceProperties.hasBeenCustomized() ? resourceProperties : webProperties.getResources());
  15. this.mvcProperties = mvcProperties;
  16. this.beanFactory = beanFactory;
  17. this.messageConvertersProvider = messageConvertersProvider;
  18. this.resourceHandlerRegistrationCustomizer = (WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer)resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
  19. this.dispatcherServletPath = dispatcherServletPath;
  20. this.servletRegistrations = servletRegistrations;
  21. this.mvcProperties.checkConfiguration();
  22. }

看到开头使用@EnableConfigurationProperties 注解引入了两个properties 类,之后(上15行)在构造其中将这两个类注入到属性中

进入注解的{WebMvcProperties.class 类中看到

  1. @ConfigurationProperties(
  2. prefix = "spring.mvc"
  3. )
  4. public class WebMvcProperties {
  5. private org.springframework.validation.DefaultMessageCodesResolver.Format messageCodesResolverFormat;
  6. private Locale locale;
  7. private WebMvcProperties.LocaleResolver localeResolver;
  8. private final WebMvcProperties.Format format;
  9. private boolean dispatchTraceRequest;
  10. ...
  11. }

原理一目了然,,现在我们可以根据这些属性在配置文件中修改它的属性

  1. spring:
  2. mvc:
  3. locale:

我们在yml中配置的locale,就可以通过@ConfigurationProperties映射到类中的locale中,然后在通过自动配置类,将这些属性配置到配置类中。

WebMvcConfigurer配置类

  • WebMvcConfigurer配置类其实是Spring内部的一种配置方式,采用JavaBean的形式来代替传统的xml配置文件形式进行针对框架个性化定制,可以自定义一些Handler,Interceptor,ViewResolver,MessageConverter。基于java-based方式的spring mvc配置,需要创建一个配置类并实现WebMvcConfigurer 接口;

常用的方法

  1. // 拦截器配置
  2. void addInterceptors(InterceptorRegistry var1);
  3. //视图跳转控制器
  4. void addViewControllers(ViewControllerRegistry registry);
  5. //静态资源处理
  6. void addResourceHandlers(ResourceHandlerRegistry registry);
  7. /* 默认静态资源处理器 */
  8. void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer);
  9. // 这里配置视图解析器
  10. void configureViewResolvers(ViewResolverRegistry registry);
  11. //配置内容裁决的一些选项
  12. void configureContentNegotiation(ContentNegotiationConfigurer configurer);
  13. //解决跨域问题
  14. public void addCorsMappings(CorsRegistry registry) ;
  1. addInterceptors:拦截器
  • addInterceptor:需要一个实现HandlerInterceptor接口的拦截器实例
  • addPathPatterns:用于设置拦截器的过滤路径规则;addPathPatterns("/**")对所有请求都拦截
  • excludePathPatterns:用于设置不需要拦截的过滤规则
  • 拦截器主要用途:进行用户登录状态的拦截,日志的拦截等。
  1. addViewControllers:页面跳转
    从写ddViewControllers 方法可以实现页面跳转
  1. public void addViewControllers(ViewControllerRegistry registry) {
  2. registry.addViewController("/toLogin").setViewName("login");
  3. }
  1. addResourceHandlers:静态资源
    比如,我们想自定义静态资源映射目录的话,只需重写addResourceHandlers方法即可。
  1. public void addResourceHandlers(ResourceHandlerRegistry registry) {
  2. registry.addResourceHandler("/my/**").addResourceLocations("classpath:/my/");
  3. }
  • addResoureHandler:指的是对外暴露的访问路径
  • addResourceLocations:指的是内部文件放置的目录
  1. 解释一下跨域
  • 跨域:指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制。

thymeleaf 模板引擎

Thymeleaf是一个Java模板引擎,支持html、xml、text、javascript、css、raw这几种模型。
使用Thymeleaf首先需要引入命名空间

  1. <html xmlns:th="http://www.thymeleaf.org">

基本使用方法

  • 引用web静态资源
    Thymeleaf通过”@{}”来引用web静态资源,例如:
  1. <script th:src="@{bootstrap/js/boostrap.min.js}"></script>1
  • 访问model模型中的数据,例如访问一个user对象的name属性
  1. <span th:text="${user.name}"></span>1
  • 数据迭代
    例如迭代一个userlist集合
  1. <tr th:each="user : ${userlist}">
  2. <td th:text="${user.name}">tyrone</td>
  3. <td th:text="${user.age}">18</td>
  4. </tr>1234

使用th:each做循环迭代,并使用${对象.属性}来访问具体的值

  • 判断是否为空
  1. <tr th:if="${messages.empty}">
  2. <td colspan="3">No messages</td>
  3. </tr>123
  • 在Javascript中访问model模型数据
  1. <script th:inline="javascript">
  2. var user = [[${user}]]
  3. console.log(user.name + "\t" + user.age);
  4. </script>1234

通过添加th:inline=”javascript”到script标签来访问model模型数据
通过”[[${}]]”这种格式来获取具体的值

示例

pojo层

  1. public class Department {
  2. private Integer id;
  3. private String name;
  4. }
  5. public class Employee {
  6. private Integer id;
  7. private String name;
  8. private Integer sex;
  9. private Department dpt;
  10. }

构造器其他方法是同Lombok实现

dao层

  1. @Repository //表示这是一个数据库访问层(Dao层)组件
  2. public class EmployeesDao {
  3. @Autowired //将Department注入
  4. private DepartmentDao departmentDao;
  5. private static Map<Integer, Employee> map = null;
  6. static {
  7. map = new HashMap<Integer, Employee>();
  8. map.put(1,new Employee(1,"wang",1,new Department(1,"学习部")));
  9. map.put(2,new Employee(2,"zahng",1,new Department(2,"小卖部")));
  10. map.put(3,new Employee(3,"li",1,new Department(3,"后勤部")));
  11. map.put(4,new Employee(4,"liu",1,new Department(4,"保卫部")));
  12. }
  13. private static Integer into = 5; //主键自增
  14. //新建一个员工
  15. public boolean addOne(Employee e){
  16. e.setId(into);
  17. map.put(into++,e);
  18. return true;
  19. }
  20. //获取全部员工信息
  21. public Collection<Employee> getAll(){
  22. return map.values();
  23. }
  24. //通过id获取员工信息
  25. public Employee getOneById(Integer id){
  26. return map.get(id);
  27. }
  28. //通过id删除员工
  29. public void del(Integer id){
  30. map.remove(id);
  31. }
  32. }
  1. @Repository
  2. public class DepartmentDao {
  3. private static Map<Integer, Department> map = null;
  4. static {
  5. map = new HashMap<Integer, Department>();
  6. map.put(1,new Department(1,"学习部"));
  7. map.put(2,new Department(2,"小卖部"));
  8. map.put(3,new Department(3,"后勤部"));
  9. map.put(4,new Department(4,"保卫部"));
  10. }
  11. //获得所有部门信息
  12. public Collection<Department> getDep(){
  13. return map.values();
  14. }
  15. //通过id h获取部门
  16. public Department getById(Integer id){
  17. return map.get(id);
  18. }
  19. }
  • 这里使用map模拟了数据库

主页设置

方法一: 使用控制器组件用一个控制器解析“/” 还有 “index.html” 这些请求会跳转到主页(不推荐)

  1. @Controller //控制器组件
  2. public class IndexController {
  3. @RequestMapping({"/","/index.html"}) //请求映射器,有多组用{}处理
  4. public String index(){
  5. return "index";
  6. }
  7. }

方法二: 添加视图管理

  1. @Configuration //定义配置类组件, 可以替换xml
  2. public class MyConfig implements WebMvcConfigurer {
  3. @Override
  4. public void addViewControllers(ViewControllerRegistry registry) {
  5. registry.addViewController("/").setViewName("index");
  6. //创建一个视图控制器,将 "/" 设置视图名为"index"
  7. registry.addViewController("/index.html").setViewName("index");
  8. //创建一个视图控制器,将 "/index" 设置视图名为"index"
  9. }
  10. }

实现登录功能

与jsp 类似前端使用form 表单提交数据到了后台,后台演示用Spring 映射

  1. @Controller
  2. public class UserController {
  3. @PostMapping("/user/login")
  4. public String Login(@RequestParam("username") String name, @RequestParam("password") String pwd, Model model){
  5. if(name.equals("admin") && pwd.equals("123456")){
  6. //登录成功
  7. return "redirect:/main";
  8. }
  9. else{
  10. model.addAttribute("msg","用户名或密码错误");
  11. return "index";
  12. }
  13. }
  14. }

使用从定向用mian请求定位到show视图,在配置器里面添加配置

  1. registry.addViewController("/main").setViewName("show");

设置拦截器

上面的方法防止用户直接使用url跳入后台main, 所以需要配置一个拦截器

  1. public class LoginInterceptor implements HandlerInterceptor {
  2. @Override
  3. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  4. String name = (String) request.getSession().getAttribute("name");
  5. if(name == null){
  6. request.setAttribute("msg", "没有登录,请先登录");
  7. request.getRequestDispatcher("/index.html").forward(request,response);
  8. return false;
  9. }
  10. else{
  11. return true;
  12. }
  13. }
  14. }
  • 新建一个类使其实现HandlerInterceptor接口的
  • 使用preHandle 方法经过判断之后返回true / false 对应为是否放行

完了之后需要在我们自己的配置类中配置

  1. @Override
  2. public void addInterceptors(InterceptorRegistry registry) {
  3. registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**")
  4. .excludePathPatterns("/","/index.html","/user/login","/css/*","/images/*","/js/*");
  5. }
  • 添加一个拦截器

  • registry.addInterceptor(new LoginInterceptor()) 将我们上面写的拦截器类LoginInterceptor()加到注册表 registry 中。

  • addPathPatterns("/**") 添加拦截器需要拦截的请求。 全部

  • excludePathPatterns("/","/index.html","/user/login","/css/*","/images/*","/js/*") 在前一步拦截请求的范围类有哪些使需要排除的 这里的请求是没有登录也可以使用的

Druid数据源

  • 提供非常优秀的监控功能
    编写配置文件
  1. spring:
  2. datasource:
  3. username: root
  4. password: Aa123456
  5. jdbcurl: jdbc:mysql://localhost:3306/computer?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
  6. driver-class-name: com.mysql.cj.jdbc.Driver
  7. type: com.alibaba.druid.pool.DruidDataSource
  8. #配置初始化大小、最小、最大线程数
  9. initialSize: 5
  10. minIdle: 5
  11. # CPU核数+1,也可以大些但不要超过20,数据库加锁时连接过多性能下降
  12. maxActive: 20
  13. # 最大等待时间,内网:800,外网:1200(三次握手1s)
  14. maxWait: 60000
  15. timeBetweenEvictionRunsMillis: 60000
  16. # 配置一个连接在池中最大空间时间,单位是毫秒
  17. minEvictableIdleTimeMillis: 300000
  18. validationQuery: SELECT 1
  19. testWhileIdle: true
  20. # 设置从连接池获取连接时是否检查连接有效性,true检查,false不检查
  21. testOnBorrow: true
  22. # 设置从连接池归还连接时是否检查连接有效性,true检查,false不检查
  23. testOnReturn: true
  24. # 可以支持PSCache(提升写入、查询效率)
  25. poolPreparedStatements: true
  26. # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
  27. filters: stat,wall,log4j
  28. # 保持长连接
  29. keepAlive: true
  30. maxPoolPreparedStatementPerConnectionSize: 20
  31. useGlobalDataSourceStat: true
  32. connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

进行配置

  1. @Configuration
  2. public class DruidConfig {
  3. @ConfigurationProperties(prefix = "spring.datasource")
  4. public DataSource druidDatasource(){
  5. System.out.println("ok");
  6. return new DruidDataSource();
  7. }
  8. //将drui数据源加载到容器里面
  9. //配置Druid 监控
  10. //1、配置一个后台的Servlet
  11. @Bean
  12. public ServletRegistrationBean statViewServlet(){
  13. ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
  14. //后台登录得账号密码配置
  15. Map<String, String> initParameters = new HashMap<>();
  16. //增加配置 key是固定的loginUsername,loginPassword
  17. initParameters.put("loginUsername","admin");
  18. initParameters.put("loginPassword","123456");
  19. //允许谁可以访问
  20. initParameters.put("allow","");
  21. bean.setInitParameters(initParameters);
  22. return bean;
  23. }
  24. //2、配置一个web 监控的filter
  25. @Bean
  26. public FilterRegistrationBean webStatFilter() {
  27. FilterRegistrationBean bean = new FilterRegistrationBean();
  28. bean.setFilter(new WebStatFilter());
  29. Map<String, String> initParams = new HashMap<>();
  30. initParams.put("exclusions", "*.js,*.css,/druid/*");
  31. bean.setInitParameters(initParams);
  32. bean.setUrlPatterns(Arrays.asList("/*"));
  33. return bean;
  34. }
  35. }

整合MyBatis

异步 @Async

SpringBoot 使用@Async 可以实现异步功能,需要在主启动类DemoApplication 添加开启异步2EnableAsync 即可

定时执行 @Scheduled

SpringBoot 可以使用@Scheduled 创建定时任务

使用注解@EnableScheduling 开启定时任务