springboot


前言

在这里插入图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

一、什么是springboot

1.1、回顾什么是spring

spring是为了解决企业级应用开发的复杂性而创建的,简化开发

spring是如何简化Java开发的

1、基于POJO的轻量级和最小侵入性编程
2、通过IOC,依赖注入(DI)和面向接口实现松耦合
3、基于切面(AOP)和惯例进行声明式编程
4、通过切面和模版减少样式代码

1.2、什么是springboot

1.3、springboot的优点

  • 为所有Spring开发者更快的入门
  • 开箱即用,提供各种默认配置来简化项目配置。
  • 内嵌式容器简化Web项目
  • 没有冗余代码生成和XML配置的要求

二、微服务架构

2.1、什么是微服务

微服务是一种架构风格,它要求我们在开发一个应用的时候,这个应用必须构建成一系列小服务的组合;可以通过http的方式进行互通。要说微服务架构,先得说说过去我们的单体应用架构。

2.2、单体应用架构

所谓单体应用架构(all in one)是指,我们将一个应用的中的所有应用服务都封装在一个应用中。无论是ERP、CRM或是其他什么系统,你都把数据库访问,web访问,等等各个功能放到一个war包内。

优点:

  • 易于开发和测试;
  • 十分方便部署;
  • 当需要扩展时,只需要将war复制多份,然后放到多个服务器上,再做个负载均衡就可以了。

缺点:

  • 哪怕我要修改一个非常小的地方,我都需要停掉整个服务,重新打包、部署这个应用war包。特别是对于一个大型应用,我们不可能吧所有内容都放在一个应用里面,我们如何维护、如何分丁合作都是问题。

三、第一个SpringBoot程序

配置:

  • jdk1.8
  • maven3.6.1
  • springboot最新版
  • IDEA

该端口号:server.port=8081

3.1、原理初深

pom.xml

  • spring-boot-dependencie:核心依赖在父工程中
  • 我们在写或者引入一些SPringboot依赖的时候,不需要指定版本,就因为有这些版本仓库

启动器

 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter</artifactId>
     </dependency>
 <dependency>
  • 启动器:说白了就是Springboot的启动场景
  • 比如spring-boot-starter-web,他就会帮我们自动导入web环境所有的依赖!
  • springboot会将所有的功能场景,都变成一个个的启动器
  • 我们要使用什么功能,就只需要找到对应的启动器就可以了 ‘ starter ’

主程序

/@SpringBootApplication:标注这个类是一个springbot的应用
@SpringBootApplication
public class HelloworldApplication {
    public static void main(String[] args) {
        //将springboot应用启动,应用反射,该方法返回一个configurableApplicationContext对象
        //参数一、应用入口的类  参数类:命令行参数
        SpringApplication.run(HelloworldApplication.class, args);
    }
}
  • 注解
@SpringBootConfiguration:springboot的配置
	@Configuration:spring配置类
	@Component:说明这是一个spring的组件

@EnableAutoConfiguration
	@AutoConfigurationPackage:自动配置包
			@Import({AutoConfigurationPackages.Registrar.class}):导入选择器‘包注册’
	@Import({AutoConfigurationImportSelector.class}):自动配置导入选择
	//获取所有的配置
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, 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;
    }

结论:springboot所有的配置都是在启动的时候扫描并加载:spring.factories所有的自动配置类都在这里,但是不一定生效,要判断条件是否成立,只要导入了对应的start,就有对应的启动器了,有了启动器,我们自动配置就会生效,然后配置就成功

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

SpringApplication.run分析【分析该方法主要分两部分:一是SpringApplication的实例化,二是run方法的执行】

  • SpringApplication
    这个类主要做了四件事情
    1、推断应用的类型是普通的项目还是Web项目
    2、查找并加载所有可用初始化器,设置到initializers属性中
    3、找出所有的应用程序监听器,设置到listeners属性中
    4、推断并设置main方法的定义类,找到运行的主类

四、yaml语法讲解

4.1、配置文件

springboot使用一个全局的配置文件,配置文件名称是固定的

  • application.properties

    • 语法结构:key=value
  • application.yml

    • 语法结构:key:空格 value

配置文件的作用:修改springboot自动配置的默认值,因为springboot在底层都给我们自动配置好了

4.2、YAML

yaml配置:

server:
	port: 80800

xml配置

<server>
	<port>8081</port>
</server>

在这里插入图片描述

4.3、给属性赋值的几种方式

遇到的问题
这里导入配置文件处理器就行了
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> </dependency>
在这里插入图片描述

程序实现

1、将默认的application.properties后缀修改为yml
2、编写实体类

//person类
@Component//组成bean
@ConfigurationProperties(prefix = "person")
/*
	ConfigurationProperties作用:
	将配置文件中的每一个属性的值,映射到这个组件中,告诉springboot将本类中的所有属性和配置文件中相关的配置进行绑定
	参数prefix=“person”:将配置文件中的person下面的所有属性一一对应

	只有这个组件是容器中的组件,才能使用容器提供的ConfigurationProperties功能
*/
public class Person {
    private String name;
    private Integer age;
    private Boolean happy;
    private Date birth;
    private Map<String,Object> maps;
    private List<Object> lists;
    private Dog dog;
    //省略get/set方法和构造器方法
}

//动物类
public class Dog {
    private String name;
    private Integer age;
 //省略get/set方法和构造器方法

3、导入配置文件处理器

   <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
   </dependency>

4、编写yml配置文件

基础语法:
k:(空格)v
以此来表示一对键值对;以空格的缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的

person:
  name: 小徐
  age: 18
  happy: false
  birth: 2022/03/29
  maps: {k1: v1,k2: v2}
  lists:
    - code
    - music
    - girl
  dog:
    name: 旺财
    age: 3

5、调试

@SpringBootTest
class Springboot02ConfigApplicationTests {
    @Autowired
    private Person person;
    @Test
    void contextLoads() {
        System.out.println(person);
    }
}

比较
## JSR303校验

结论:

  • 配置yml和配置properties都可以获取到值,强烈推荐yml
  • 如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用一下@value
  • 如果说,我们专门编写了一个JavaBean来和配置文件进行映射,就直接使用
    @configurationProperties,不要犹豫!

4.4、配置文件加载位置

springboot启动会扫描以下位置的application.properties或者application.yml文件作为Springboot的默认配置文件
在这里插入图片描述

4.5、多环境配置

在这里插入图片描述

五、Springboot Web开发

自动装配

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

5.1、静态资源【03】

总结:
1、在springboot中我们可以使用以下方式处理静态资源

  • webjars ——loca1host:8080/webjars/
  • public,static,/**,resources —— localhost :8080/
    2、优先级:resources>static(默认)>public

5.2、模板引擎

第一步:导入thymeleaf

<!--Thymeleaf-->
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-java8time</artifactId>
        </dependency>

第二步:将html页面放在templates里
在这里插入图片描述

<body>
<!--所有的html元素都可以被thymeleaf替换接管: th:元素名-->
    <div th:text="${msg}"></div>
	<hr/>
	<h3 th:each="user:${user}" th:text="${user}"></h3>
</body>

第三步,测试

//@RestController:返回一个字符串
//在templates目录下的所有页面,只能通过controller来跳转
@Controller
public class HelloController {
    @GetMapping("/test1")
    public String hello(Model model){
        model.addAttribute("msg","hello templates");
        //遍历
        model.addAttribute("user", Arrays.asList("小徐","小双"));
        return "test";
    }
}


thymeleaf语法
https://www.jianshu.com/p/d1370aeb0881

员工管理系统:
1、首页配置:所有页面的静态资源配置都需要使用thymeleaf接管
2、页面国际化:

  • 1、我们需要配置i18n文件
  • 2、我们如果需要在项目中进行按钮自动切换,我们需要自定义一个国际化主键【LocaleResolver】
  • 记得将自己写的组件配置到spring容器中【@Bean】

六、Springboot整合数据库

6.1、整合JDBC

1、依赖:jdbc API、Mysql Driver
2、 配置数据库文件【application.yml】

spring:
  datasource:
    username: root
    password: xuxiaoqiang1234
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver

3、测试数据库连接【springboot04DateApplicationTests】

@SpringBootTest
class Springboot04DataApplicationTests {
    @Autowired
    DataSource dataSource;
    @Test
    void contextLoads() throws SQLException {
        //查看以下默认的数据源:class com.zaxxer.hikari.HikariDataSource
        System.out.println(dataSource.getClass());
        System.out.println("nihao ");
        //获得数据库连接
        Connection connection=dataSource.getConnection();
        System.out.println(connection);
        //xxxx Template:springboot已经配置好模板bean,拿来即用CRUD
        //关闭
        connection.close();
    }
}

4、数据库的增删改查【JdbcController】

@RestController
public class JdbcController {
    @Autowired
    JdbcTemplate jdbcTemplate;
    //查询数据库的所有信息
    //没有实体类,数据库的东西怎么获取?用map
    @GetMapping("/user")
    public List<Map<String,Object>> query(){
        String sql="select * from user ";
        List<Map<String, Object>> list_maps = jdbcTemplate.queryForList(sql);
        return list_maps;
    }
    //添加数据
    @GetMapping("/addUser")
    public String addUser(){
        String sql="insert into mybatis.user(id,name,pwd) values(5,'双','32123')";
        System.out.println(sql);
        jdbcTemplate.update(sql);
        return "addUser-ok";
    }
    //修改数据
    @GetMapping("/upDateUser/{id}")
    public String upDateUser(@PathVariable("id") int id){
        String sql="update mybatis.user set name=?,pwd=? where id="+id;
        //封装
        Object[] objects = new Object[2];
        objects[0]="邱";
        objects[1]="43234";
        jdbcTemplate.update(sql,objects);
        return "upDateUser-ok";
    }

    //删除数据
    @GetMapping("/deleteUser/{id}")
    public String deleteUser(@PathVariable("id") int id){
        String sql="delete from mybatis.user where id=?";
        jdbcTemplate.update(sql,id);
        return "deleteUser-ok";
    }
}

6.2、整合Druid数据源

1、引入数据源

		 <!--Druid-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.5</version>
        </dependency>

2、指定使用druid的数据源【application.yml】

  type: com.alibaba.druid.pool.DruidDataSource

3、测试

@SpringBootTest
class Springboot04DataApplicationTests {
    @Autowired
    DataSource dataSource;
    @Test
    void contextLoads() throws SQLException {
        //查看以下默认的数据源:class com.zaxxer.hikari.HikariDataSource
        System.out.println(dataSource.getClass());
        System.out.println("nihao ");
        //获得数据库连接
        Connection connection=dataSource.getConnection();
        System.out.println(connection);
        //xxxx Template:springboot已经配置好模板bean,拿来即用CRUD
        //关闭
        connection.close();
    }
}

七、 整合Mybatis框架

1、导入依赖

 <!--mybatis-spring-boot-starter:整合-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>

2、配置数据库信息
【application.properties】

spring.datasource.username=root
spring.datasource.password=xuxiaoqiang1234
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

3、测试


@SpringBootTest
class Springboot05MybatisApplicationTests {
@Autowired
    DataSource dataSource;
    @Test
    void contextLoads() throws SQLException {
        System.out.println(dataSource.getClass());
        System.out.println(dataSource.getConnection());
    }
}

4、写UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kuang.mapper.UserMapper">
   <!-- 查询所有用户-->
    <select id="queryUserList" resultType="User">
        select * from user
     </select>
    <!--查询一个用户-->
    <select id="queryUserById" resultType="User">
        select * from user where id = #{id}
    </select>
    <!--增加一个用户-->
    <insert id="addUser" parameterType="User">
        insert into user (id,name,pwd) values (#{id},#{name},#{pwd})
    </insert>
    <!--修改一个用户-->
    <update id="updateUser" parameterType="User">
        update user set name=#{name},pwd=#{pwd} where id = #{id}
    </update>
    <!--删除一个用户-->
    <delete id="deleteUser" parameterType="int">
        delete from user where id =#{id}
    </delete>
</mapper>

5、整合mybatis【application.properties】

#整合mybatis
mybatis.type-aliases-package=com.kuang.pojo
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml

6、编写接口【UserMapper】

@Mapper//表示这是一个mybatis的mapper类
@Repository
public interface UserMapper {
    //查询所有用户
    List<User> queryUserList();
    //查询一个用户
    User queryUserById(int id);
    //增加一个用户
    int addUser(User user);
    //修改一个用户
    int updateUser(User user);
    //删除一个用户
    int deleteUser(int id);

}

7、执行增删改查

@RestController
public class UserController {
    @Autowired
    private UserMapper userMapper;
    //查询所有用户
    @GetMapping("/queryUserList")
    public  List<User> queryUserList(){
        List<User> userList = userMapper.queryUserList();
        for (User user : userList) {
            System.out.println(user);
        }
        return userList;
    }
    //增加一个用户
    @GetMapping("addUser")
    public String addUser(){
        User user=new User();
        user.setId(5);
        user.setName("娇");
        user.setPwd("78326");
        userMapper.addUser(user);
        return "Ok";
    }
    @GetMapping("updateUser")
    //修改一个用户
    public String updateUser(){
        User user=new User();
        user.setId(1);
        user.setName("李丽");
        user.setPwd("64326");
        userMapper.updateUser(user);
        return "Ok";
    }
    //删除一个用户
    @GetMapping("deleteUser")
    public String deleteUser(){
        userMapper.deleteUser(3);
        return "Ok";
    }
}

八、SpringSecurity(安全)

8.1、初识

SpringSecurity 是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型,他可以实现强大的Web安全控制,对于安全控制,我们仅需要引入spring-boot-starter-security模块,进行少量的配置,即可实现强大的安全管理!

记住几个类

  • websecurityConfigurerAdapter:自定义Security策略
  • AuthenticationManagerBuilder:自定义认证策略
  • @EnableWebSecurity:开启WebSecurity模式

Spring Security的两个主要目标是“认证"和“授权”(访问控制)

8.2、案例

@EnableWebSecurity
public class SecunrityConfig 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();
         //开启注销功能
        http.logout();
    }

    //认证,springboot 2.1.x可以直接使用
    //在spring Secutity 5.0+新增了很多加密的方法:passwordEncoder(new BCryptPasswordEncoder())
    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        //这些数据正常应该从数据库中读取
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("小徐").password(new BCryptPasswordEncoder().encode("12345")).roles("vip2","vip3")
                .and()
                .withUser("双").password(new BCryptPasswordEncoder().encode("1234")).roles("vip1")
                .and()
                .withUser("root").password(new BCryptPasswordEncoder().encode("123")).roles("vip2","vip2","vip3");
    }
}

错误: There is no PasswordEncoder mapped for the id “null”

  • 在spring Secutity 5.0+新增了很多加密的方法:passwordEncoder(new BCryptPasswordEncoder())

九、Swagger

9.1、springboot集成swagger

1、新建一个springboot=web项目【springboot-07-swagger】
2、导入相关依赖

<!--swagger-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

3、编写一个Hello工程

@RestController
public class HelloController {
  @RequestMapping("/hello")
    public  String  hello(){
        return "hello";
    }
}

4、配置swagger==》config

@Configuration
@EnableSwagger2//开启swagger2
public class SwaggerConfig {

}

5、测试运行【http://localhost:8080/swagger-ui.html】
在这里插入图片描述

9.2、配置swagger

1、Swagger的bean实例Docket

@Configuration
@EnableSwagger2//开启swagger2
public class SwaggerConfig {
    //配置了swagger的Docket的bean实例
    @Bean
    public Docket docket(){
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());
    }

2、配置Swagger信息=apiInfo

 //配置Swagger信息=apiInfo
    private ApiInfo apiInfo() {
        //作者信息
        Contact contact=new Contact("小徐","https://www.bilibili.com/","2318654821@qq.com");
        return new ApiInfo(
                "小徐的天地",
                "彼方自有荣光在",
                "1.0",
                "urn:tos",
                contact,
                "Apache 2.0",
                "http://www.apache.org/licenses/LICENSE-2.0",
                new ArrayList());
    }
}

在这里插入图片描述

9.3、Swagger配置扫描接口

Docket.select()

@Configuration
@EnableSwagger2//开启swagger2
public class SwaggerConfig {
    //配置了swagger的Docket的bean实例
    @Bean
    public Docket docket(){
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                //RequestHandlerSelectors:配置要扫描接口的方式
                //basePackage:指定要扫描的包
                //any:扫描全部
                //none:不扫描
                //withClassAnnotation:扫描类上的注解,参数是一个注解的反射对象
                //withMethodAnnotation:扫描方法上的注解
                .apis(RequestHandlerSelectors.basePackage("com.kuang.controller"))
                //paths():过滤什么路径
                .paths(PathSelectors.ant("/kuang/**"))
                .build();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值