大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
SpringBoot框架
自动装配原理
注解部分
pom.xml
- spring-boot-dependencies: 核心依赖在父工程中
- 我们在写或者引入一些SpringBoot依赖的时候,不需要指定版本,就因为有这些版本仓库
启动器
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency>
- SpringBoot的启动场景;
- 比如spring-boot-starter-web,他就会帮我们自动导入web环境所有的依赖
- SpringBoot会将所有的功能场景,都变成一个个的启动器
- 我们要使用什么功能,就只需要找到对应的启动器就可以了
starter
主程序
注解: @springBootApplication
–
概括:SpringBoot所有自动配置都是在启动的时候扫描并加载:“META-INF/spring.factories”,所有的自动配置类都在这里,但是不一定生效,要判断条件是否成立,只要导入了对应的start,就有对应的启动器了,然后自动装配就会生效,然后就配置成功了
- SpringBoot在启动的时候,从类路径下META-INF/spring.factories获取指定的值
- 将这些自动配置的类导入容器,自动配置就会生效
- 以前我们需要自动配置的东西,现在SpringBoot帮我们做了
- 整合JavaEE,解决方案和自动配置的东西都在spring-boot-autoconfigure 下
- 他会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器
- 容器中也会存在非常多的xxxAutoConfiguration,就是这些类给容器中导入了这个场景需要的所有组件,并自动配置@Configuration
- 有了自动配置类,免去了我们手动编写配置文件的工作
启动Run部分
1.推断应用的类型是普通的项目还是Web项目
2.查找并加载所有可用初始化器,设置到initializers属性中
3.找出所有的应用程序监听器,设置到listeners属性中
4.推断并设置main方法的定义类,找到运行的主类
具体配置类分析
package org.springframework.boot.autoconfigure.web.servlet;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.boot.web.servlet.server.Encoding;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.filter.CharacterEncodingFilter;
/** * {@link EnableAutoConfiguration Auto-configuration} for configuring the encoding to use * in web applications. * * @author Stephane Nicoll * @author Brian Clozel * @since 2.0.0 */
//表示这是配置类,交由Spring配置
@Configuration(proxyBeanMethods = false)
//自动配置属性
//ServerProperties里面有@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true),刚好对应yaml里面的配置
@EnableConfigurationProperties(ServerProperties.class)
//Spring的底层注解:根据不同的条件,来判断当前配置或者类是否生效
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "server.servlet.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {
private final Encoding properties;
public HttpEncodingAutoConfiguration(ServerProperties properties) {
this.properties = properties.getServlet().getEncoding();
}
@Bean
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(Encoding.Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(Encoding.Type.RESPONSE));
return filter;
}
@Bean
public LocaleCharsetMappingsCustomizer localeCharsetMappingsCustomizer() {
return new LocaleCharsetMappingsCustomizer(this.properties);
}
static class LocaleCharsetMappingsCustomizer
implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>, Ordered {
private final Encoding properties;
LocaleCharsetMappingsCustomizer(Encoding properties) {
this.properties = properties;
}
@Override
public void customize(ConfigurableServletWebServerFactory factory) {
if (this.properties.getMapping() != null) {
factory.setLocaleCharsetMappings(this.properties.getMapping());
}
}
@Override
public int getOrder() {
return 0;
}
}
}
xxxAutoConfiguration…向容器中自动配置组件
xxxProperties:自动配置类,装配配置文件中自定义的一些内容
yaml
基本语法
#k=v
#空格要求十分高
#注入到我们的配置中,可以直接给实体类赋值
# 普通的key-value
name: QSH
#对象
student1:
name: QSH
age: 3
#行内写法
student2: {
name: QSH,age: 3}
#数组
pets:
- cat
- dog
- pig
pets2: [cat,dog,pig]
JSR303校验
空检查
@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 对象是否符合正则表达式的规则,被注释的元素符合制定的正则表达式,regexp:正则表达式 flags: 指定 Pattern.Flag 的数组,表示正则表达式的相关选项。
数值检查
建议使用在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=) 被指定的元素必须在合适的范围内
@Range(min=10000,max=50000,message=”range.bean.wage”)
@Valid 递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证)
@CreditCardNumber信用卡验证
@Email 验证是否是邮件地址,如果为null,不进行验证,算通过验证。
@ScriptAssert(lang= ,script=, alias=)
@URL(protocol=,host=, port=,regexp=, flags=)
捕捉校验异常,返回提示信息
对于程序可能有很多的校验注解,可能会出现多个校验错误,我们可以定义一个统一的异常处理类,帮我们捕捉校验错误并返回提示信息,这里可以利用Spring的ControllerAdvice技术。
(1).编写统一异常处理类
package io.renren.app.exception;
import io.renren.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import java.util.HashMap;
import java.util.Map;
/** * @Author zunhui * @Email Qiangzunhui@126.com * @Date 2020/8/5 13:45 * @Description 统一异常处理 */
@RestControllerAdvice(basePackages = "io.renren.app.controller")
@Slf4j
public class AppManageControllerAdvices {
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public R handleVaildException(MethodArgumentNotValidException e) {
log.error("数据校验出现问题{},异常类型:{}", e.getMessage(), e.getClass());
BindingResult bindingResult = e.getBindingResult();
Map<String, String> errorMap = new HashMap<>();
bindingResult.getFieldErrors().forEach((fieldError) -> {
errorMap.put(fieldError.getField(), fieldError.getDefaultMessage());
});
return R.error(400, "数据校验失败").put("data", errorMap);
}
@ExceptionHandler(value = Throwable.class)
public R handleException(Throwable throwable) {
log.error("错误:", throwable);
return R.error(500, "系统未知异常");
}
}
分组校验(多场景的复杂校验)
对于不同的操作,字段校验的规则和数量可能是不同的,所以我们将校验规则分组,对于不同的操作进行不同的校验组,使用groups属性。
1.想要使用分组校验功能,根据文档我们首先编写不同的校验组接口,只编写空接口,用来表示就可以了:
//新增分组
public interface AddGroup{
}
//修改分组
public interface UpdateGroup{
}
2.编写好分组接口,对于不同的检验规则,标注不同的分组标识:
@NotNull ( message ="修改必须指定id",groups = {
UpdateGroup.class})
@Null(message = "新增不能指定id",groups = {
AddGroup.class})
@TableId
private Long Id;
@NotBlank(message="名称必须提交",groups={
AddGroup.class,UpdateGroup.class})
private String name;
3.在controller方法上标注不同的分组校验,使用@Validated注解:
//保存
@RequestMapping("/save")
//@RequiresPermissions("product:brand:save")
public R save(@Validated({
AddGroup.class}) @RequestBody BrandEntity brand){
brandService.save(brand);
return R.ok();
}
@Validated({AddGroup.class}):启用不同的分组校验规则。
注意:在使用分组校验的情况下,对于没有标注分组的校验规则,默认是不生效的,只有标注了分组的校验规则才会生效。
配置文件
配置文件位置及优先级
- file: ./ config/
- file: ./
- classpath: / config/
- classpath : /
多环境下配置环境
WEB开发
要解决的问题:
-
导入静态资源…
-
首页
-
jsp, 模板引擎Thymeleaf
-
thymeleaf依赖
-
装配扩展SpringMVC
-
增删改查
-
拦截器
-
国际化
静态资源
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
ServletContext servletContext = getServletContext();
addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (servletContext != null) {
registration.addResourceLocations(new ServletContextResource(servletContext, SERVLET_LOCATION));
}
});
}
总结:
- 在SpringBoot中我们可以使用以下方式处理静态资源
- webjars (localhost:8080/webjars)
- public,static,/**,resources (localhost:8080)
- 优先级:resources > static(默认) > public
Thymeleaf模板引擎
要使用,需导入starter依赖!我们将html放在我们的clsspath下的templates
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.4.3</version>
</dependency>
语法
表达式
html用法
扩展MVC
在springboot中,有非常多的xxxx Configuration帮助我们进行扩展配置
package com.example.demo2.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.Locale;
//扩展springmvc
//如果你想diy一些定制化的功能,只要写这个组件,然后将它交给springboot,springboot就会帮我们自动装配!
@Configuration
//此标签一加,则官方的mvc自动配置全部失效
@EnableWebMvc
public class MyMvcConfig implements WebMvcConfigurer {
@Bean
public ViewResolver myViewResolver () {
return new MyViewResolver();
}
//自定义一个自己的视图解析器
public static class MyViewResolver implements ViewResolver {
@Override
public View resolveViewName(String viewName, Locale locale) throws Exception {
return null;
}
}
}
整合Mybatis
整合包
mybatis-spring-boot-starter
- 导入包
<!--引入mybatis,这是Mybatis官方提供的适配SpringBoot的,而不是SpringBoot自己的-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
- 配置yml文件
# 配置spring自带的数据源
spring:
datasource:
username: root
password: root
url: jdbc:mysql://localhost:3306/mybatis?userSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
# 整合mybatis
mybatis:
# 别名
type-aliases-package: com.kuang.pojo
# mapper文件位置
mapper-locations: classpath:mybatis/mapper/*.xml
- mybatis配置
- User
@Data @AllArgsConstructor @NoArgsConstructor public class User { private int id; private String name; private String password; }
- UserMapper接口
@Repository @Mapper public interface UserMapper { public User queryUserByName(String name); }
- UserMapper.xml配置文件
<!--namespace=绑定一个指定的Dao/Mapper接口--> <mapper namespace="com.kuang.mapper.UserMapper"> <select id="getUserList" resultType="com.kuang.pojo.User" parameterType="String"> select * from USER where name = #{name} </select> </mapper>
- 编写sql
- service层调用dao层
- UserService 接口
public interface UserService { public User queryUserByName(String name); }
- UserServiceImpl实现类
@Service public class UserServiceImpl implements UserService{ @Autowired UserMapper mapper; public User queryUserByName(String name) { User user = mapper.queryUserByName(name); return user; } }
- controller调用service层
@Autowired UserServiceImpl userService; public void mian(String args[]){ User user = userService.queryUserByName("dog"); }
SpringSecurity
- 引入 Spring Security 模块
- 编写 Spring Security 配置类
参考官网:https://spring.io/projects/spring-security - 编写基础配置类
- 定制请求的授权规则
- 定义认证规则
//AOP : 拦截器 @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { // 链式编程 @Override //授权 protected void configure(HttpSecurity http) throws Exception { //首页所有人可以访问,功能页只有对应有权限的人才能访问 //请求授权的规则 http.authorizeRequests() .antMatchers("/").permitAll() .antMatchers("/level1/**").hasRole("vip1") .antMatchers("/level2/**").hasRole("vip2") .antMatchers("/level3/**").hasRole("vip3"); //没有权限默认会到登录页面,需要开启登录的页面 http.formLogin() .loginPage("/toLogin") .usernameParameter("username") .passwordParameter("password") .loginProcessingUrl("/login"); http.csrf().disable();//关闭csrf功能:跨站请求伪造,默认只能通过post方式提交logout请求 // 开启注销功能 http.logout().logoutSuccessUrl("/"); //开启记住我功能 http.rememberMe().rememberMeParameter("rememberme"); } //认证 @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //在内存中定义,也可以在jdbc中去拿.... //Spring security 5.0中新增了多种加密方式,也改变了密码的格式。 //要想我们的项目还能够正常登陆,需要修改一下configure中的代码。我们要将前端传过来的密码进行某种方式加密 //spring security 官方推荐的是使用bcrypt加密方式。 auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()) .withUser("kuangshen").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3") .and() .withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3") .and() .withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1"); } }
Shiro
- Subject 用户
- SecurityManager 管理用户
- Realm 连接数据
- 导入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.kuang</groupId>
<artifactId>shiro-springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>shiro-springboot</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--shiro-thymeleaf整合-->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.22</version>
</dependency>
<!--引入mybatis,这是Mybatis官方提供的适配SpringBoot的,而不是SpringBoot自己的-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 编写Shiro配置类
package com.example.Config;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
//ShiroFilterFactoryBean
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
//设置安全管理器
factoryBean.setSecurityManager(securityManager);
//添加shiro的内置过滤器
/*anon: 无须认证就可以访问 * authc: 必须认证了才能访问 * user: 必须拥有 记住我 功能才适用 * perm: 拥有对某个角色权限才能访问*/
Map<String, String> param = new LinkedHashMap<>();
// param.put("/user/add", "authc");
// param.put("/user/update", "authc");
//授权,如果未授权会跳转到未授权界面noauth
param.put("/user/add", "perms[user:add]");
param.put("/user/update", "perms[user:update]");
param.put("/user/*", "authc");
factoryBean.setFilterChainDefinitionMap(param);
//设置登录的请求
factoryBean.setLoginUrl("/toLogin");
factoryBean.setUnauthorizedUrl("/noauth");
return factoryBean;
}
//DefaultWebSecurityManager
@Bean(name="securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm);
return securityManager;
}
//Realm对象创建,自定义类
@Bean
public UserRealm userRealm (){
return new UserRealm();
}
//整合shiroDialect
@Bean
public ShiroDialect getShiroDialect () {
return new ShiroDialect();
}
}
- 自定义UserRealm
package com.example.Config;
import com.example.pojo.User;
import com.example.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import static java.awt.SystemColor.info;
public class UserRealm extends AuthorizingRealm {
@Autowired
UserService userService;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
System.out.println("执行了=>授权doGetAuthorizationInfo");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//拿到当前登录的这个对象
Subject subject = SecurityUtils.getSubject();
User cuurrentUser = (User)subject.getPrincipal();
info.addStringPermission(cuurrentUser.getPerms());
return info;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("执行了=>认证doGetAuthorizationInfo");
//用户名密码
// String name = "root";
// String password = "123";
UsernamePasswordToken userToken=(UsernamePasswordToken)token;
User user = userService.queryUserByName(userToken.getUsername());
if (user == null) {
return null;
}
// Subject subject = SecurityUtils.getSubject();
// subject.getSession().setAttribute("loginUser", user);
return new SimpleAuthenticationInfo(user, user.getPwd(),"");
}
}
- 整合MyBatis
- 编写实体类
- 编写mapper接口、mapper.xml、application.yml配置mybatis(别名,mapper.xml文件位置)
- 编写service接口,serviceImpl类
Swagger
简介
前后端分离时代:
- 后端:后端控制层,服务层,数据访问层
- 前端:前端控制层,视图层
Swagger :
- 号称世界上最流行的API框架;
- RestFul Api文档在线自动生成工具 => Api文档与Api定义同步更新
- 直接运行,可以在线测试API接口
- 支持多种语言:(Java , Php…)
SpringBoot集成Swagger
- 建一个SpringBoot – web 工程
- 导入相关依赖
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
- 编写一个Hello工程
- 配置Swagger ==> Config
@Configuration
@EnableSwagger2 //开启Swagger
public class SwaggerConfig {
}
- 测试运行:http://localhost:8080/swagger-ui.html
配置Swagger信息
@Configuration
@EnableSwagger2 //开启Swagger
public class SwaggerConfig {
//配置了Swagger 的Docket的bean实例
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());
}
//配置Swagger信息=apiInfo
public ApiInfo apiInfo(){
//作者信息
Contact contact = new Contact("Daniel","https://www.baidu.com","denglianqing@qq.com");
return new ApiInfo("Dainel的SwaggerAPI文档",
"天道酬勤",
"v1.0",
"urn:tos",
contact, "Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList());
}
}
Swagger配置扫描接口
Docket.select()
package com.example.demoswagger.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.VendorExtension;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
@Configuration
@EnableSwagger2 //开启swagger
public class SwaggerConfig {
//配置了Swagger的docket的Bean实例
@Bean
public Docket docket(Environment environment) {
//设置要显示的swagger环境
Profiles profiles = Profiles.of("dev", "test");
//获取项目的环境
//通过environment.acceptsProfiles判断是否处在自己设定的环境
boolean b = environment.acceptsProfiles(profiles);
return new Docket(DocumentationType.SWAGGER_2)
//如果为false,swagger不会启动
.apiInfo(apiInfo())
// .enable(b)
.select()
//RequestHandlerSelectors 配置要扫描接口的方式
//basePackage : 指定要扫描的包
//any : 扫描全部
//none : 不扫描
//withClassAnnotation : 扫描类上的注解
//withMethodAnnotation : 扫描方法上的注解
.apis(RequestHandlerSelectors.basePackage("com.example.demoswagger.controller"))
//过滤哪些路径
// .paths(PathSelectors.ant("/example/** "))
.build();
}
//配置了Swagger的docket的Bean实例
private ApiInfo apiInfo () {
return new ApiInfo("QSH日记",
"好日记",
"v1.0",
"https://baidu.com",
new Contact("qsh", "https://baidu.com", "11@qq.com"),
"Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList<VendorExtension>());
}
}
题目:我只希望我的Swagger在生产环境中使用,在发布的时候不使用
- 判断是不是生产环境 flag = false
- 注入enable (flag)
//配置了Swagger 的Docket的bean实例
@Bean
public Docket docket(Environment environment){
//设置要显示的Swagger环境
Profiles profiles = Profiles.of("dev","test");
//通过 environment.acceptsProfiles 判断是否处在自己设定的环境中
boolean flag = environment.acceptsProfiles(profiles);
...
}
配置API文档的分组
@Bean
public Docket docket1() {
return new Docket(DocumentationType.SWAGGER_2).groupName("A");
}
@Bean
public Docket docket2() {
return new Docket(DocumentationType.SWAGGER_2).groupName("B");
}
@Bean
public Docket docket3() {
return new Docket(DocumentationType.SWAGGER_2).groupName("C");
}
接口注释
总结:
- 我们可以通过Swagger给一些比较难理解的属性或者接口,增加注释信息;
- 接口文档实时更新
- 可以在线测试
任务
异步任务
- 给要实现异步任务加上注解 @Async
@Service
public class AsyncService {
@Async
public void hello(){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("数据正在处理...");
}
}
- 在main方法开启异步功能 @EnableAsync
@EnableAsync // 开启异步注解功能
@SpringBootApplication
public class Springboot09TaskApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot09TaskApplication.class, args);
}
}
邮件任务
- 导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
- 配置邮箱和密码
spring.mail.username=514906666@qq.com
spring.mail.password=xxyyzzhhll
spring.mail.host=smtp.qq.com
# 开启加密验证
spring.mail.properties.mail.smtp.ssl.enable=true
- 测试发送邮件(组合邮件,带附件)
@SpringBootTest
class Springboot09TaskApplicationTests {
@Autowired
JavaMailSenderImpl mailSender;
@Test
void contextLoads2() throws MessagingException {
//一个复杂的邮件
MimeMessage mimeMessage = mailSender.createMimeMessage();
//组装
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
//正文
helper.setSubject("Test");
helper.setText("<h2 style='color:red'> 这是一封测试邮件 </h2>",true);
//附件
helper.addAttachment("data1",new File("D:\\testdata\\2017-01-01.xls"));
helper.setTo("dishifu@126.com");
helper.setFrom("514906666@qq.com");
mailSender.send(mimeMessage);
}
定时任务
- TaskScheduler 任务调度者
- TaskExecutor 任务执行者
- @EnableScheduling 开启定时功能的注解
- @Scheduled 什么时候执行
- Cron表达式
- 编写定时服务
@Service
public class ScheduledService {
//在一个特定的时间执行这个方法
//cron 表达式
//秒 分 时 日 月 周几
/* 30 17 17 * * ? 每天10点15分30 执行一次 30 0/5 10,18 * * ? 每天10点和18点,每隔五分钟执行一次 */
@Scheduled(cron = "30 17 17 * * ?")
public void Hello(){
System.out.println("hello,被执行了!");
}
}
- 在启动类开启定时功能
@EnableAsync // 开启异步注解功能
@EnableScheduling //开启定时功能的注解
@SpringBootApplication
public class Springboot09TaskApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot09TaskApplication.class, args);
}
}
整合Redis
分布式Dubbo + Zookeeper
zookeeper :注册中心
dubbo-admin : 监控管理后台,查我们注册了哪些服务,哪些服务被消费了
Dubbo:jar包
步骤:
前提:zookeeper服务已启动
- 提供者提供服务
-
导入依赖
-
配置注册中心的地址,以及服务发现名,和要扫描的包
-
在想要被注册的服务上面,再增加一个注解**@Service**(dubbo包下的)
- 消费者如何消费
- 导入依赖
- 配置注册中心的地址,配置自己的服务名
- 从远程注入服务 @Reference
SpringCloud大概
微服务架构存在的问题:
分布式架构会遇到的四个核心问题
- 这么多服务,客户端该如何去访问
- 这么多服务,服务之间如何进行通信
- 这么多服务,如何管理
- 服务挂了,该怎么办
==》 解决方案:
SpringCloud,是一套生态,就是用来解决以上分布式架构的4个问题。
想使用SpringCloud,必须掌握SpringBoot,因为SpringCloud是基于SpringBoot的
- API网关,服务路由
- HTTP,RPC框架,异步调用
- 服务注册与发现,高可用
- 熔断机制,服务降级
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/171263.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...