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)


相关推荐

  • Typora——MarkDown学习笔记

    Typora——MarkDown学习笔记一级标题:# 文字二级标题:## 文字三级标题:### 文字字体粗体:文字两边加**斜体:文字两边加*斜体并加粗:文字两边加***删除文字:两边加~~引用:>+空格分割线:— 或者***图片:![截图](图片路径)超链接:点击跳转排序:排序号:1. 2. 3.无序:·回车表格名字性别生日张三男19990513代码:skdsldl…

  • Java手机号码正则表达式验证,手机号段根据2020年最新号段所做参考「建议收藏」

    Java手机号码正则表达式验证,手机号段根据2020年最新号段所做参考「建议收藏」最近需要实现java手机号码正则表达式验证,然而百度了一下发现结果挺多的,但是好像号段不全,基本上都是几年前的结果,大部分刚好就没我166的号段,我今天也查了一下最新的手机号段,重新写一遍。2020年最新的号段我参考自:https://m.jihaoba.com/tools/haoduan/目前的移动号段:139、138、137、136、135、134、147、150、151、152、157、158、159、172、178、182、183、184、187、188、198.联通号段:130、131、13

  • MySQL相关问题整理

    MySQL相关问题整理备注:针对基本问题做一些基本的总结,不是详细解答!1.事务的基本要素2.事务隔离级别(必考)3.如何解决事务的并发问题(脏读,幻读)(必考)4.MVCC多版本并发控制(必考)5.为什么选择B+树作为索引结构(必考)6.索引B+树的叶子节点都可以存哪些东西(必考)7.查询在什么时候不走(预期中的)索引(必考)8.sql如何优化9.explain是如何解析sql的…

  • idea 激活码 lom【在线注册码/序列号/破解码】

    idea 激活码 lom【在线注册码/序列号/破解码】,https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

  • 各种窗口最小化快捷键详解「建议收藏」

    各种窗口最小化快捷键详解「建议收藏」一、ALT+Esc可以使当前窗口最小化。二、Win+D最小化所有窗口,再按一下就可以还原窗口。三、Windows+M最小化所有窗口。四、Windows+Shift+M还原最小化的窗口。五、A

  • 数据集成之主数据管理(一)基础概念篇

    数据集成之主数据管理(一)基础概念篇

    2021年11月14日

发表回复

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

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