狂神说 SpringBoot 笔记

课程链接:https://www.bilibili.com/video/BV1PE411i7CV?from=search&seid=3765473467792965977

狂神说Java SpringBoot

狂神说SpringBoot01:Hello,World!

狂神说SpringBoot02:运行原理初探

狂神说SpringBoot03:yaml配置注入

狂神说SpringBoot04:JSR303数据校验及多环境切换

狂神说SpringBoot05:自动配置原理

狂神说SpringBoot06:自定义starter

狂神说SpringBoot07:整合JDBC

狂神说SpringBoot08:整合Druid

狂神说SpringBoot09:整合MyBatis

狂神说SpringBoot10:Web开发静态资源处理

狂神说SpringBoot11:Thymeleaf模板引擎

狂神说SpringBoot12:MVC自动配置原理

狂神说SpringBoot13:页面国际化

狂神说SpringBoot14:集成Swagger终极版

狂神说SpringBoot15:异步、定时、邮件任务

狂神说SpringBoot16:富文本编辑器

狂神说SpringBoot17:Dubbo和Zookeeper集成

狂神说SpringBoot18:集成SpringSecurity

一、运行原理初探

  • 注解:

狂神说 SpringBoot 笔记_第1张图片

//获取所有配置
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes);

获取候选配置:

    protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
        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.");
        return configurations;
    }

二、JSR303数据校验及多环境切换

  1. 配置文件加载位置

狂神说 SpringBoot 笔记_第2张图片

file : 文件路径,就是项目路径

狂神说 SpringBoot 笔记_第3张图片

三、SpringBoot Web开发

自动装配:

SpringBoot到底帮我们配置了什么?我们能不能进行修改?能修改哪些东西?能不能扩展?

  • xxxAutoConfiguration…向容器中自动配置组件
  • xxxProperties:自动配置类,装配配置文件中自定义的一些内容

要解决的问题:

  • 导入静态资源…

  • 首页

  • jsp, 模板引擎Thymeleaf

    thymeleaf依赖

  • 装配扩展SpringMVC

  • 增删改查

  • 拦截器

  • 国际化

四、员工管理系统

  1. 首页配置
    1. 注意点,所有页面的静态资源都需要使用thymeleaf接管;(导入thymeleaf依赖)
    2. url: @{}
  2. 页面国际化
    1. 我们需要配置i18n文件
    2. 我们如果需要在项目中进行按钮自动切换,我们需要自定义一个组件LocaleResolver
    3. 记得将自己写的组件配置到spring容器@Bean
    4. #{}

五、整合MyBatis

整合包

mybatis-spring-boot-starter

  1. 导入包

    
    <dependency>
        <groupId>org.mybatis.spring.bootgroupId>
        <artifactId>mybatis-spring-boot-starterartifactId>
        <version>2.1.1version>
    dependency>
    
  2. 配置yml文件

    application.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
    
  3. 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配置文件

      
      <mapper namespace="com.kuang.mapper.UserMapper">
          <select id="getUserList" resultType="com.kuang.pojo.User" parameterType="String">
          select * from USER where name = #{name}
        	select>
      mapper>
      
  4. 编写sql

  5. 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;
          }
      }
      
  6. 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. 编写基础配置类

    • 定制请求的授权规则
    • 定义认证规则
    //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 连接数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FBMQ6DqA-1594654577784)(D:\我\MyBlog\狂神说Java SpringBoot.assets\image-20200713105531285.png)]

简单实验:

  1. 导入依赖

    <dependency>
        <groupId>org.apache.shirogroupId>
        <artifactId>shiro-springartifactId>
        <version>1.5.3version>
    dependency>
    
  2. 编写Shiro配置类

    @Configuration
    public class ShrioConfig {
        //ShiroFilterFactoryBean : Step3
        @Bean
        public ShiroFilterFactoryBean getShrioFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
            ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
            //设置安全管理器
            bean.setSecurityManager(defaultWebSecurityManager);
            return bean;
        }
        
        //DefaultWebSecurityManager : Step2
        @Bean("securityManager")
        public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
            //关联userRealm
            securityManager.setRealm(userRealm);
            return securityManager;
        }
        
        //创建 realm 对象, 需要自定义类:Step1
        @Bean
        public UserRealm userRealm(){
            return new UserRealm();
        }
    }
    
  3. 自定义UserRealm

    //自定义的 UserRealm
    public class UserRealm extends AuthorizingRealm {
    
        //授权
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            return null;
        }
    
        //认证
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
            return null;
        }
    }
    

一个小Demo:

  1. 导入依赖

    • springboot-mybatis整合
    • shiro-thymelea整合
    
    <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.0modelVersion>
        <parent>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-parentartifactId>
            <version>2.3.1.RELEASEversion>
            <relativePath/> 
        parent>
        <groupId>com.kuanggroupId>
        <artifactId>shiro-springbootartifactId>
        <version>0.0.1-SNAPSHOTversion>
        <name>shiro-springbootname>
        <description>Demo project for Spring Bootdescription>
    
        <properties>
            <java.version>1.8java.version>
        properties>
    
        <dependencies>
            
            <dependency>
                <groupId>com.github.theborakompanionigroupId>
                <artifactId>thymeleaf-extras-shiroartifactId>
                <version>2.0.0version>
            dependency>
    
            <dependency>
                <groupId>mysqlgroupId>
                <artifactId>mysql-connector-javaartifactId>
                <version>8.0.20version>
            dependency>
            
            <dependency>
                <groupId>log4jgroupId>
                <artifactId>log4jartifactId>
                <version>1.2.17version>
            dependency>
            <dependency>
                <groupId>com.alibabagroupId>
                <artifactId>druidartifactId>
                <version>1.1.22version>
            dependency>
            
            <dependency>
                <groupId>org.mybatis.spring.bootgroupId>
                <artifactId>mybatis-spring-boot-starterartifactId>
                <version>2.1.1version>
            dependency>
            <dependency>
                <groupId>org.projectlombokgroupId>
                <artifactId>lombokartifactId>
                <version>1.18.12version>
            dependency>
            <dependency>
                <groupId>org.apache.shirogroupId>
                <artifactId>shiro-springartifactId>
                <version>1.5.3version>
            dependency>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-thymeleafartifactId>
            dependency>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
    
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-testartifactId>
                <scope>testscope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintagegroupId>
                        <artifactId>junit-vintage-engineartifactId>
                    exclusion>
                exclusions>
            dependency>
        dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.bootgroupId>
                    <artifactId>spring-boot-maven-pluginartifactId>
                plugin>
            plugins>
        build>
    
    project>
    
  2. 整合MyBatis

    • 编写实体类
    • 编写mapper接口、mapper.xml、application.yml配置mybatis(别名,mapper.xml文件位置)
    • 编写service接口,serviceImpl类
  3. 编写Shiro配置类

    @Configuration
    public class ShrioConfig {
    
        //ShiroFilterFactoryBean : Step3
        @Bean
        public ShiroFilterFactoryBean getShrioFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
            ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
            //设置安全管理器
            bean.setSecurityManager(defaultWebSecurityManager);
    
            //添加shiro的内置过滤器
            /*
                anno: 无需认证就可以访问
                authc: 必须认证了才可以访问
                user: 必须拥有 记住我 功能才能用
                perms: 拥有对某个资源的权限才能访问
                role: 拥有某个角色权限才能访问
            */
    
            Map<String, String> filterMap = new LinkedHashMap<>();
    
            //用户授权,正常情况下没有授权会跳转到授权页面
            filterMap.put("/user/add","perms[user:add]");
            filterMap.put("/user/update","perms[user:update]");
    
            //拦截
            //filterMap.put("/user/add","authc");
            //filterMap.put("/user/update","authc");
            filterMap.put("/user/*","authc");
    
            //设置登录请求
            bean.setLoginUrl("/toLogin");
            //设置未授权页面
            bean.setUnauthorizedUrl("/noauth");
            bean.setFilterChainDefinitionMap(filterMap);
            return bean;
        }
    
        //DefaultWebSecurityManager : Step2
        @Bean("securityManager")
        public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
            //关联userRealm
            securityManager.setRealm(userRealm);
            return securityManager;
        }
    
        //创建 realm 对象, 需要自定义类:Step1
        @Bean
        public UserRealm userRealm(){
            return new UserRealm();
        }
    
        //整合 ShiroDialect:用来整合shiro thymeleaf
        @Bean
        public ShiroDialect getShiroDialect(){
            return new ShiroDialect();
        }
    }
    
  4. 自定义UserRealm

    //自定义的 UserRealm
    public class UserRealm extends AuthorizingRealm {
    
        @Autowired
        UserServiceImpl userService;
    
        //授权
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            System.out.println("执行了 => doGetAuthorizationInfo");
    
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            // 拿到当前登录的这个对象
            Subject subject = SecurityUtils.getSubject();
            // 拿到User对象
            User currentUser = (User) subject.getPrincipal();
            // 设置当前用户的权限
            System.out.println(currentUser.getName() + "的权限为 " + currentUser.getPerms());
            info.addStringPermission(currentUser.getPerms());
    
            return info;
        }
    
        //认证
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
            System.out.println("执行了 => 认证AuthenticationToken");
    
            UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;
            //连接真实的数据库
            User user = userService.queryUserByName(userToken.getUsername());
            if(user == null){
                //没有这个人
                return null; //抛出异常 UnknownAccountException
            }
    
            // 登录成功 将用户信息存入session
            Subject currentSubject = SecurityUtils.getSubject();
            Session session = currentSubject.getSession();
            session.setAttribute("loginUser",user.getName());
    
            // 密码认证,shiro做
            return new SimpleAuthenticationInfo(user,user.getPassword(),"");
        }
    }
    

案例详细代码:https://gitee.com/daniel1996/shiro_springboot/tree/master/shiro-springboot

你可能感兴趣的:(SpringBoot)