SpringBoot框架_若依框架怎么样

SpringBoot框架_若依框架怎么样SpringBoot框架

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新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,就有对应的启动器了,然后自动装配就会生效,然后就配置成功了

  1. SpringBoot在启动的时候,从类路径下META-INF/spring.factories获取指定的值
  2. 将这些自动配置的类导入容器,自动配置就会生效
  3. 以前我们需要自动配置的东西,现在SpringBoot帮我们做了
  4. 整合JavaEE,解决方案和自动配置的东西都在spring-boot-autoconfigure 下
  5. 他会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器
  6. 容器中也会存在非常多的xxxAutoConfiguration,就是这些类给容器中导入了这个场景需要的所有组件,并自动配置@Configuration
  7. 有了自动配置类,免去了我们手动编写配置文件的工作

启动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}):启用不同的分组校验规则。

注意:在使用分组校验的情况下,对于没有标注分组的校验规则,默认是不生效的,只有标注了分组的校验规则才会生效。

配置文件

配置文件位置及优先级

在这里插入图片描述

  1. file: ./ config/
  2. file: ./
  3. classpath: / config/
  4. 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));
}
});
}

在这里插入图片描述
总结:

  1. 在SpringBoot中我们可以使用以下方式处理静态资源
  • webjars (localhost:8080/webjars)
  • public,static,/**,resources (localhost:8080)
  1. 优先级: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

  1. 导入包
<!--引入mybatis,这是Mybatis官方提供的适配SpringBoot的,而不是SpringBoot自己的-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
  1. 配置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
  1. mybatis配置
    1. User
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User { 
    
    private int id;
    private String name;
    private String password;
    }
    
    1. UserMapper接口
    @Repository
    @Mapper
    public interface UserMapper { 
    
    public User queryUserByName(String name);  
    }
    
    1. 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>
    
    1. 编写sql
    2. service层调用dao层
      1. UserService 接口
      public interface UserService { 
      
      public User queryUserByName(String name);
      }
      
      1. UserServiceImpl实现类
      @Service
      public class UserServiceImpl implements UserService{ 
      
      @Autowired
      UserMapper mapper;
      public User queryUserByName(String name) { 
      
      User user = mapper.queryUserByName(name);
      return user;
      }
      }
      
      1. controller调用service层
      @Autowired
      UserServiceImpl userService;
      public void mian(String args[]){ 
      
      User user = userService.queryUserByName("dog");
      }
      

SpringSecurity

  1. 引入 Spring Security 模块
  2. 编写 Spring Security 配置类
    参考官网:https://spring.io/projects/spring-security
  3. 编写基础配置类
    1. 定制请求的授权规则
    2. 定义认证规则
      //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 连接数据
    在这里插入图片描述
  1. 导入依赖
<?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>
  1. 编写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();
}
}
  1. 自定义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(),"");
}
}
  1. 整合MyBatis
    • 编写实体类
    • 编写mapper接口、mapper.xml、application.yml配置mybatis(别名,mapper.xml文件位置)
    • 编写service接口,serviceImpl类
      在这里插入图片描述

Swagger

简介

前后端分离时代:

  • 后端:后端控制层,服务层,数据访问层
  • 前端:前端控制层,视图层

Swagger :

  • 号称世界上最流行的API框架;
  • RestFul Api文档在线自动生成工具 => Api文档与Api定义同步更新
  • 直接运行,可以在线测试API接口
  • 支持多种语言:(Java , Php…)

SpringBoot集成Swagger

  1. 建一个SpringBoot – web 工程
  2. 导入相关依赖
<!-- 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>
  1. 编写一个Hello工程
  2. 配置Swagger ==> Config
@Configuration
@EnableSwagger2 //开启Swagger
public class SwaggerConfig { 

}
  1. 测试运行: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");
}

接口注释

在这里插入图片描述

总结:

  1. 我们可以通过Swagger给一些比较难理解的属性或者接口,增加注释信息;
  2. 接口文档实时更新
  3. 可以在线测试

任务

异步任务

  1. 给要实现异步任务加上注解 @Async
@Service
public class AsyncService { 

@Async
public void hello(){ 

try { 

Thread.sleep(3000);
} catch (InterruptedException e) { 

e.printStackTrace();
}
System.out.println("数据正在处理...");
}
}
  1. 在main方法开启异步功能 @EnableAsync
@EnableAsync // 开启异步注解功能
@SpringBootApplication
public class Springboot09TaskApplication { 

public static void main(String[] args) { 

SpringApplication.run(Springboot09TaskApplication.class, args);
}
}

邮件任务

  1. 导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
  1. 配置邮箱和密码
spring.mail.username=514906666@qq.com
spring.mail.password=xxyyzzhhll
spring.mail.host=smtp.qq.com
# 开启加密验证
spring.mail.properties.mail.smtp.ssl.enable=true
  1. 测试发送邮件(组合邮件,带附件)
@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表达式
  1. 编写定时服务
@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,被执行了!");
}
}
  1. 在启动类开启定时功能
@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服务已启动

  1. 提供者提供服务
  • 导入依赖

  • 配置注册中心的地址,以及服务发现名,和要扫描的包
    在这里插入图片描述

  • 在想要被注册的服务上面,再增加一个注解**@Service**(dubbo包下的)

  1. 消费者如何消费
  • 导入依赖
  • 配置注册中心的地址,配置自己的服务名
    在这里插入图片描述
  1. 从远程注入服务 @Reference

SpringCloud大概

微服务架构存在的问题:

分布式架构会遇到的四个核心问题

  • 这么多服务,客户端该如何去访问
  • 这么多服务,服务之间如何进行通信
  • 这么多服务,如何管理
  • 服务挂了,该怎么办
    ==》 解决方案:

​ SpringCloud,是一套生态,就是用来解决以上分布式架构的4个问题。

​ 想使用SpringCloud,必须掌握SpringBoot,因为SpringCloud是基于SpringBoot的

  1. API网关,服务路由
  2. HTTP,RPC框架,异步调用
  3. 服务注册与发现,高可用
  4. 熔断机制,服务降级
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/171263.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(1)
blank

相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号