springboot笔记

1 springboot的介绍

  1. 样板化配置。springboot可以简化我项目的配置,让我们ssm项目的配置变得更加简单。
  2. 内置了tomcat服务器。以后的web项目不用部署了,直接运行main方法后,就启动了tomcat,tomcat里面就有了我们的项目。

2 搭建springboot的开发环境

  1. 配置jdk的版本,因为springboot2依赖了spring5,spring5又依赖了jdk1.8,所以我们的项目至少是jdk1.8.

    pom.xml文件中修改jdk的版本。

      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
      </properties>
    
  2. 引入依赖。引入一个就可以了。这一个就相当于spring的核心jar包和springmvc的相关jar包。

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.1.4.RELEASE</version>
    </dependency>
    
  3. 开发控制器类。跟以前一样。

    
    @RestController//@Controller+@ResponseBody
    public class UserController {
        @GetMapping("/users")//设置请求方式只能是get请求
        public Map test(String name){
            System.out.println(name+"==================");
            //响应的数据
            Map map=new HashMap();
            map.put("a","zhangsan");
            map.put("b","20");
            return map;
        }
    }
    
  4. 写main方法启动tomcat。这时可以访问该项目了。

    注意:

    1. 类名叫Application
    2. 类必须建在com.baizhi。只有建在这个包里面,springboot才会扫描本包以及子包中的注解。
    3. 在这类上面添加注解。@SpringBootApplication
    @SpringBootApplication
    public class Application {
        public static void main(String[] args) {
            //启动springboot框架
            SpringApplication.run(Application.class,args);
        }
    }
    
  5. 测试运行。默认tomcat的端口号是8080,我们需要写配置文件对端口号进行修改。

    application.properties放在resources文件夹里面。

    #tomcat的端口号
    server.port=8989
    #项目的项目名,以后我们访问该项目http://ip:port/context-path
    server.servlet.context-path=/springboot_day1
    
    

    3 springboot的配置文件

    有两种配置方式。

    1. application.properties配置。
    2. application.yml配置。

    两者配置的内容是一样的。只是配置方式不一样。

    yml用来替换properties文件。两者都叫application,放的位置也一样都在resources里面。

    server:
      port: 8989
      servlet:
        context-path: /springboot_day1
    

    yml是通过缩进(两个空格)来指定关系的。

4 mybatis跟springboot集成

  1. 引入依赖。

    <!--mybatis跟springboot集成的依赖-->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.3.2</version>
    </dependency>
    <!--mybatis要链接mysql数据库,mysql数据库的驱动-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.38</version>
    </dependency>
    
  2. 在application.yml里面配置数据源信息。

    #配置数据库的连接信息
    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/idea_day1?useUnicode=true&characterEncoding=utf8
        username: root
        password: 123456
        driver-class-name: com.mysql.jdbc.Driver
    #给实体起别名,设置映射文件的路径。
    mybatis:
      type-aliases-package: com.baizhi.entity
      mapper-locations: classpath:com/baizhi/dao/*.xml
    
  3. 写实体类,dao接口,dao的mapper文件。

    跟以前一样

  4. 在dao接口上面添加注解。

    @Mapper//这个注解是让springboot识别dao接口,自动生成dao的实现类,并让spring管理起来。

    让spring管理dao有两个注解可以选择:

    1. 在dao接口上面添加@Mapper,这种方式需要每个dao都添加。

    2. 在springboot的启动类上面扫描dao包。管理dao对象。

      @SpringBootApplication
      @MapperScan("com.baizhi.dao")//扫描dao包
      public class Application {
          public static void main(String[] args) {
              SpringApplication.run(Application.class,args);
          }
      }
      
  5. 测试dao。

    参考下一个步骤,跟junit集成。

5 springboot跟junit进行集成测试

  1. 引入依赖。

    <!--junit单元测试的依赖-->
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.12</version>
          <scope>test</scope>
        </dependency>
        <!--springboot做单元测试的依赖-->
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-test</artifactId>
          <version>2.1.4.RELEASE</version>
        </dependency>
    
  2. 在测试类上使用注解。@SpringBootTest

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = Application.class)
    public class TestDao {
        //飘红不影响使用
        @Autowired
        private StudentDao studentDao;
        @Test
        public void testSelectAll(){
            List<Student> students = studentDao.selectAll();
    
            students.forEach(System.out::println);
        }
        
    }
    

6 springboot和业务类的相关配置

业务类的作用控制事务,mybatis插件分页。

6.1 控制事务

  1. 我们可以在类上面添加注解。@Transactional来标注这个类 中所有的方法都开启事务。
  2. 我们可以在查询方法上面添加 @Transactional(readOnly=true)表示查询方法上面不使用回滚段以此来提高查询速度。@Transactional(propagation = Propagation.REQUIRED)表示增删改方法都必须使用事务。

@Service
@Transactional//表示在当前类中所有的方法都要开启事务
public class StudentServiceImpl implements StudentService {
    @Autowired
    private StudentDao studentDao;
    @Transactional(readOnly = true)//查询方法的事务策略是只读
    @Override
    public List<Student> selectAll() {
        return studentDao.selectAll();
    }
    @Transactional(readOnly = true)
    @Override
    public PageInfo<Student> selectByPage(int curPage, int pageSize) {
        PageHelper.startPage(curPage,pageSize);
        List<Student> students = studentDao.selectAll();
        PageInfo<Student> pi=new PageInfo<>(students);
        return pi;
    }
}

6.2 使用mybatis的插件实现分页

  1. 引入mybatis插件依赖。跟以前的依赖不一样。
    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper-spring-boot-starter</artifactId>
      <version>1.2.5</version>
    </dependency>
  1. 业务类的写法跟以前一样。

7 springboot里面使用过滤器

前置知识:springboot管理bean对象第一种方式是使用注解@Component ,另外一种方式如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P2iwdzrI-1630934033921)(springboot笔记.assets/image-20201129163744322.png)]

springboot中的很多配置都是通过类来完成的。我们配置拦截器类的时候也是在config包里面添加一个配置类。

  1. 定义过滤器,跟以前一样。

    package com.baizhi.filter;
    
    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class AccessControlAllowFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
    
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    		....;
    		chain.doFilter(request,response);
        }
    
        @Override
        public void destroy() {
    
        }
    }
    
    
  2. 写配置类

    @Configuration
    public class MywebConfig  implements WebMvcConfigurer {
        @Bean
        public FilterRegistrationBean filterRegist() {
            FilterRegistrationBean frBean = new FilterRegistrationBean();
            frBean.setFilter(new AccessControlAllowFilter());
            frBean.addUrlPatterns("/*");
            return frBean;
        }
    }
    

8 jackson

jackson是json转换工具,这些工具可以将java对象转换为json字符串。常见的转换工具:jackson,fastjson,gson

springboot里面使用jackson设置日期属性常见方式有两种:

  1. 在实体类的属性上添加注解。优先级高。

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private Date birth;
    
  2. 在yml配置文件中设置全局的日期格式。优先级低

    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/idea_day1?useUnicode=true&characterEncoding=utf8
        username: root
        password: 123456
        driver-class-name: com.mysql.jdbc.Driver
      jackson:
        date-format: yyyy-MM-dd
        time-zone: GMT+8
    

9 Rest 风格的URI

9.1 什么是REST

REST(Resource Representational State Transfer)表述性状态传递。

REST风格的URI典型示例:

传统风格URIREST风格URI
查询1个/book/showOne.do?id=1GET /books/1
查询所有/book/showAllBooks.doGET /books
添加/book/addBook.do?k=v数据POST|PUT /books + json请求数据
删除/book/removeBook.do?id=1DELETE /books/1
更新/book/updateBook.do?k=v数据PUT|POST /books/1 + json请求数据

HTTP的method:

  • GET:访问数据
  • POST:添加数据或者更新数据
  • PUT:更新数据或者添加数据
  • DELETE:删除数据

特点:

  • URI中一般不出现动词,如 show add remove update,而应该名词化。
  • 通过HTTP metod表示对资源的操作
  • 名词一般都用复数
  • 请求参数会作为地址的一部分出现

优势:

​ 和前端解耦合,可以同时支持多种客户端

9.2 Springboot中实现Restful API

  1. 在@RequestMapping配置的路径中,使用{参数名}为参数占位。

  2. 在@RequestMapping中配置method属性定义请求方法

  3. 在方法的参数前添加@PathVariable(“参数名”)获取路径中的参数,在方法的参数前添加@RequestBody注解从请求中获取json参数

    @Controller
    public class UserController {
    
        @RequestMapping(value="/login",method = RequestMethod.GET)
        public @ResponseBody Map login(String username,String password){
            System.out.println("username = [" + username + "], password = [" + password + "]");
            return new HashMap(){{
                put("status", "success");}};
        }
    
        @RequestMapping(value="/users",method=RequestMethod.POST)
        public @ResponseBody Map register(@RequestBody User u){
            System.out.println("u = [" + u + "]");
            return new HashMap(){{
                put("status", "success");}};
        }
    
        @RequestMapping(value="/users",method=RequestMethod.GET)
        public @ResponseBody List<User> showAllUsers(){
            List<User> users = new ArrayList<>();
            users.add(new User(1, "xiao1hei", "123456"));
            users.add(new User(2, "xiao2hei", "123456"));
            users.add(new User(3, "xiao3hei", "123456"));
            return users;
        }
    
        @RequestMapping(value="/users/{id}",method = RequestMethod.DELETE)
        public @ResponseBody Map removeUser(@PathVariable("id") Integer id){
            System.out.println("id = [" + id + "]");
            return new HashMap(){{
                put("status", "success");}};
        }
    
        @RequestMapping(value = "/users/{id}", method = RequestMethod.PUT)
        public @ResponseBody Map updateUser(@PathVariable("id") Integer id, @RequestBody User user) {
            System.out.println("id = [" + id + "], user = [" + user + "]");
            return new HashMap(){{
                put("status", "success");}};
        }
    }
    

注意:

SpringMVC为简化Rest风格的URI开发,提供了简化开发的注解:

  • GetMapping

    相当于:RequestMapping(method=RequestMethod.GET)

  • PostMapping

    相当于:RequestMapping(method=RequestMethod.POST)

  • PutMapping

    相当于:RequestMapping(method=RequestMethod.PUT)

  • DeleteMapping

    相当于:RequestMapping(method=RequestMethod.DELETE)

  • RestController

    相当于Controller+ResponseBody。

    替换Controller,默认类中所有的服务方法添加了ResponseBody注解。简化Rest开发,并提高了辨识度。

Rest中特殊处理:

  1. 总有一些无法名词化的功能(登陆),仍然使用原来的请求方式(uri+请求数据的格式),但响应应该使用json
  2. 对于分页(条件查询),请求参数仍然使用k=v格式的请求数据

9.3 后台测试工具postman

postman可以在没有前端页面的情况下,对后端的控制器发出请求,以此来模拟浏览器的http请求,从而对java代码进行测试。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zONRXFlK-1630934033925)(springboot笔记.assets/image-20210117112330561.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xEy4RJOq-1630934033927)(springboot笔记.assets/image-20210117113929640.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ogNVUFOF-1630934033928)(springboot笔记.assets/image-20210607173915904.png)]

10 springboot中的日志记录

springboot中是使用了logback来记录日志信息的。我们需要引入logback的配置文件放到resources文件夹里面。来打印执行的sql信息。信息的输出级别FATAL>ERROR>WARN>INFO>DEBUG

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EdynY0jg-1630934033929)(springboot笔记.assets/image-20201129154032669.png)]

11 springboot实现文件上传

  1. 写upload组件

  2. 控制器。跟以前一样。

    @RestController
    public class UserController {
        @Value("${imgPath}")//获取springboot配置文件中的变量,把配置文件中的变量赋值给该属性
        private String path;
        @PostMapping("/upload")
        public Map<String,Object> upload(MultipartFile headImg) throws IOException {
            headImg.transferTo(new File(path,headImg.getOriginalFilename()));
            return new HashMap(){{put("code",0);put("newFileName","xxxx")}};
        }
    }
    
    
  3. 把d盘普通文件夹部署到服务器上。

    #配置数据库的连接信息
    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/idea_day1?useUnicode=true&characterEncoding=utf8
        username: root
        password: 123456
        driver-class-name: com.mysql.jdbc.Driver
      resources:
        static-locations: file:${imgPath}
      servlet:
        multipart:
          max-request-size: 3MB  #设置总的请求大小
          max-file-size: 2MB   #设置单个文件上传的大小
    #设置一个路径供配置文件和controller共用
    imgPath: d:\\testImg
    

上传后,通过浏览器访问的路径:

http://ip:port/appName/(testImg文件夹里面图片的名字)

springboot中使用拦截器

  1. 写拦截器类,跟以前一样。

    
    public class MyInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
            System.out.println("===========进入了拦截器类============");
            return true;
        }
    }
    
    
  2. 写配置类。com.baizhi.config文件夹里面。

    @Configuration//该类是一个配置类
    public class MyInterceptorConfig implements WebMvcConfigurer {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            //添加MyInterceptor到注册机里面,该拦截器拦截所有的请求,排除掉/user/*的请求
            registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**")
                    .excludePathPatterns("/user/*");
        }
    }
    

AOP

在SpringBoot中,面向切面编程,需要使用注解的方式。

  1. 添加依赖

    <!-- springboot 中 aop的依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
        <version>2.1.4.RELEASE</version>
    </dependency>
    
  2. 相关注解说明

    @Aspect:切面的意思;添加在类上面;表示这个类是一个增强处理

    @Before:这个注解添加在方法上面;方法会在目标方法执行之前执行===》前置增强

    @After:添加在方法上面;方法会在目标方法执行之后执行===》后置增强

    @Around:添加在方法上;表示的是环绕增强

  3. 编码

    @Component
    @Aspect
    public class MyAspect {
        @Before("execution(* com.baizhi.service.*.*(..))")
        public void before(JoinPoint joinPoint){
            Signature signature = joinPoint.getSignature();//目标方法
            Object target = joinPoint.getTarget();//目标对象
            Object proxy = joinPoint.getThis();//代理对象
            Object[] args = joinPoint.getArgs();//方法实参
            System.out.println("signature = " + signature);
            System.out.println("target = " + target.getClass());
            System.out.println("proxy = " + proxy.getClass());
            System.out.println("args = " + args);
            System.out.println("前置增强");
        }
    
        @After("execution(* com.baizhi.service.*.*(..))")
        public void after(JoinPoint joinPoint){
            System.out.println("后置增强");
        }
    
        @Around("execution(* com.baizhi.service.*.*(..))")
        public Object around(ProceedingJoinPoint joinPoint) {
    
            Object result = null;
            try {
                System.out.println("环绕开始");
                result = joinPoint.proceed();
                System.out.println("环绕结束");
            }catch (Throwable t){
                t.printStackTrace();
                throw new RuntimeException(t);
            }
            return result;
        }
    }
    

注意:可以通过 @PointCut注解简化切点的配置

@Component
@Aspect
public class MyAspect {
    @Pointcut("execution(* com.baizhi.service.*.*(..))")
    public void pointcut(){}

    @Before("pointcut()")
    public void before(JoinPoint joinPoint){
        Signature signature = joinPoint.getSignature();//目标方法
        Object target = joinPoint.getTarget();//目标对象
        Object proxy = joinPoint.getThis();//代理对象
        Object[] args = joinPoint.getArgs();//方法实参
        System.out.println("signature = " + signature);
        System.out.println("target = " + target.getClass());
        System.out.println("proxy = " + proxy.getClass());
        System.out.println("args = " + args);
        System.out.println("前置增强");
    }

    @After("pointcut()")
    public void after(JoinPoint joinPoint){
        System.out.println("后置增强");
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) {

        Object result = null;
        try {
            System.out.println("环绕开始");
            result = joinPoint.proceed();
            System.out.println("环绕结束");
        }catch (Throwable t){
            t.printStackTrace();
            throw new RuntimeException(t);
        }
        return result;
    }
}

spring-boot-starter-parent作为父项目

pom.xml将spring-boot-starter-parent作为父项目

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.4.RELEASE</version>
  </parent>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kkOcMSE1-1630934033930)(springboot笔记.assets/wps1.jpg)]

父项目用于声明依赖,子项目引入父项目声明的依赖时,可以不用指定版本,如果子项目指定版本,则以子项目指定的版本为主

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3DgZ2J33-1630934033931)(springboot笔记.assets/wps2.jpg)]

springboot的starter机制

start机制解决的问题

这个是一个原理性的内容,理解后可以更加深刻理解springboot为什么可以简化配置。

当我们项目需要依赖第三方代码时,如果直接把第三方代码通过依赖的方式引入到我们项目中,我们是不能直接使用spring管理起来这些类的。为什么?

我们启动项目用到的启动类Application会自动读取当前包里面的注解。比如我们的Application类写在了com.baizhi包里面,那么项目运行时只能读取com.baizhi包里面的注解。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-57NB7oAA-1630934033931)(springboot笔记.assets/image-20210226164754372.png)]

上面这个图里面的children1表示第三方开发出来的代码。我们的项目要用到第三方的的类。比如UserService和NewsService。

这样我们的项目要引入第三方依赖。

<dependencies>
    <dependency>
        <groupId>com.baizhi</groupId>
        <artifactId>chidren1</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

但是我们发现UserService在我们的项目中可以正常使用,而NewsServiceImpl不能正常使用。原因就是两个包不一样。userService在com.baizhi这个包里面。我们项目Application类也在com.baizhi包里面。

要想解决这个问题。我们可以在Application里面告知要多扫描一些包。

//告知项目我们要扫描两个包中的注解
@SpringBootApplication(scanBasePackages = {"com.baizhi","org.xxx"})
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}

这样配置后newsService和UserService都可以使用了。

但是这不是一个常规做法。因为我们无法要求第三方按照我们的包结构命名,我们也不能针对每个第三方jar包都去做扫描。这时候start机制就是解决这个问题的。

start机制

我们的项目的入口Application这个类上面有个注解叫@SpringBootApplication,引入这个注解后,这个注解上面又有@EnableAutoConfiguration,@EnableAutoConfiguration这个注解可以自动扫描依赖包中resoures/META-INF/spring.factories这个文件。这个文件中可以配置要让spring管理的bean的配置类

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.baizhi.config.BeanConfigration  #配置类的全限定名

on里面告知要多扫描一些包。

//告知项目我们要扫描两个包中的注解
@SpringBootApplication(scanBasePackages = {"com.baizhi","org.xxx"})
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}

这样配置后newsService和UserService都可以使用了。

但是这不是一个常规做法。因为我们无法要求第三方按照我们的包结构命名,我们也不能针对每个第三方jar包都去做扫描。这时候start机制就是解决这个问题的。

start机制

我们的项目的入口Application这个类上面有个注解叫@SpringBootApplication,引入这个注解后,这个注解上面又有@EnableAutoConfiguration,@EnableAutoConfiguration这个注解可以自动扫描依赖包中resoures/META-INF/spring.factories这个文件。这个文件中可以配置要让spring管理的bean的配置类

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.baizhi.config.BeanConfigration  #配置类的全限定名

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kbXfAETM-1630934033932)(springboot笔记.assets/image-20210226170625570.png)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值