当前位置:   article > 正文

IT学习笔记--Spring Boot/Cloud_松哥springboot笔记

松哥springboot笔记

一、Spring Boot

1. Spring Boot简介

Spring boot特点:只使用一个核心配置文件,取消了一系列xml配置,甚至连web.xml都没有, 全部使用注解的方式完成WEB层的功能。框架内置Tomcat服务器,运行启动类中的Main函数即可启动。

它最重要的是以下四个核心:

  • 自动配置:针对很多Spring应用程序常见的应用功能, Spring Boot能自动提供相关配置。
  • 起步依赖:告诉Spring Boot需要什么功能,它就能引入需要的库。
  • 命令行界面:这是Spring Boot的可选特性,借此你只需写代码就能完成完整的应用程序,
    无需传统项目构建。
  • Actuator:让你能够深入运行中的Spring Boot应用程序,一探究竟。主要是提供在运行时检视应用程序内部情况的能力。

Spring Boot 具有如下特性:

  • 创建独立的 Spring 应用程序,为开发者提供更快的入门体验 。
  • 尽可能地 自动配置,开箱 即用 。
  • 没有代码生成, 也无须 XML 配置,同时也可以修改默认值来满足特定的需求。
  • 提供了一些大型项目中常见的非功能性特性,如嵌入式服务器、安全、指标、健康检测、外部配置等 。
  • 并不是对 Spring 功能上的增强,而是提供了 一种快速使用 Spring 的方式。

2. 工程搭建

具体可参考这篇博文:Intellij IDEA 搭建Spring Boot项目

生成的项目中,resources文件夹下,static文件夹下存放静态文件,比如css、js、html和图片等 ;templates下存放html文件,controller默认访问该文件夹下的html文件;这个在application.properties配置文件中是可以修改的。

3. @SpringBootApplication开启了Spring的组件扫描和Spring Boot的自动配置功能。实际上, @SpringBootApplication将三个有用的注解组合在了一起:

  • Spring的@Configuration:标明该类使用Spring基于Java的配置。
  • Spring的@ComponentScan:启用组件扫描,这样你写的Web控制器类和其他组件才能被自动发现并注册为Spring应用程序上下文里的Bean。
  • Spring Boot 的 @EnableAutoConfiguration :这个不起眼的小注解也可以称为@Abracadabra①,就是这一行配置开启了Spring Boot自动配置的魔力,让你不用再写成篇的配置了。

4. 使用spring boot+mybatis,使用IntelliJ IDEA开发,记录一些问题的解决方法:

1)在使用@Mapper注解方式代替XXmapper.xml配置文件,使用@Select等注解配置sql语句的情况下,如何配置数据库字段名到JavaBean实体类属性命的自动驼峰命名转换?

使用spring boot后,越来越喜欢用注解方式进行配置,代替xml配置文件方式。mybatis中也可以完全使用注解,避免使用xml方式配置mapper。

(参考  springboot(六):如何优雅的使用mybatis  http://www.ityouknow.com/springboot/2016/11/06/springboot(%E5%85%AD)-%E5%A6%82%E4%BD%95%E4%BC%98%E9%9B%85%E7%9A%84%E4%BD%BF%E7%94%A8mybatis.html

设置自动驼峰命名转换,在xml中可以直接配置mapUnderscoreToCamelCase属性。但是使用注解方式时,经过一番查找资料才找到比较好的设置方法。如下:

在spring boot的配置文件application.properties中,加入配置项:

  1. mybatis.configuration.mapUnderscoreToCamelCase=true
  2. mybatis.configuration.map-underscore-to-camel-case=true

设为true表示开启驼峰转换。经过试验,两种配置方法都可以。但如果同时配置,前者mybatis.configuration.mapUnderscoreToCamelCase的优先级更高。

参考:

官方的配置说明 mybatis-spring-boot-autoconfigure – MyBatis Sring-BootStarter | Reference Documentation  http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/#Configuration

SpringBoot之Mybatis - 王念博客  https://my.oschina.net/wangnian/blog/667764

另外查到有通过javaConfig方式,配置org.apache.ibatis.session.SqlSessionFactory的Bean,放入spring的对象池。mapUnderscoreToCamelCase是org.apache.ibatis.session.Configuration的一个属性,实例化Configuration对象并将其mapUnderscoreToCamelCase属性设为true,再使用这个Configuration对象作为SqlSessionFactory的配置即可使mapUnderscoreToCamelCase=true生效。

但是仅仅为了改变一个属性的值,就自己编码生成一个SqlSessionFactory未免太繁琐了些。使用在application.properties中配置的方法更方便。

2)mybatis管理的@Mapper的Dao,在使用@Autowire自动注入时,IDEA有红色报错“could not autowire”,但实际运行时正常,如何去除报错?

按照本人的理解,这个报错是由于Dao接口只添加了mybatis自定义的@Mapper注解,没有添加spring定义的@Component、@Repository等,所以IDEA不认为这是纳入Spring管理的Bean,导致在IDEA找不到autowire的Dao的来源。

查找解决方法,找到了这里的问答:

java - Idea inspects batis mapper bean wrong - Stack Overflow  https://stackoverflow.com/questions/25379348/idea-inspects-batis-mapper-bean-wrong

里面提到安装【MyBatis plugin】插件可以解决,但是我尝试安装这个插件并启用后,仍然有红色报错(插件已经激活,不是license导致的问题),所以猜测这个插件可能是只针对XXmapper.xml配置的方式有效,而对@Mapper注解Dao interface的方式无效(针对后一种情况是否有效,大家尝试了可以反馈下结果)。

所以只好采用一种折中的不算完美的办法,在Dao interface中添加@Mapper的同时,再添加@Repository(或者@Component也可以),如下方代码的第1行:

  1. @Repository
  2. @Mapper
  3. public interface UserDao {
  4. @Select("SELECT phone FROM user WHERE name = #{name}") //动态传入表名,可以使用 ...FROM ${tableName}... ,但需要解决sql注入风险
  5. String getPhoneByUserName(@Param("name") String name);
  6. }

5.Spring Boot核心配置文件

它的核心配置文件是application.properties;可以配置默认的tomcat端口号等;

可以进行多环境配置文件:

当resources内包含多个环境的配置文件,如:测试用的配置文件application-test.properties、开发用的配置文件application-dev.properties和上线用的配置文件application-online.properties;在核心配置文件中使用spring.profiles.active=test即可激活测试用的配置文件application-test.properties。有激活的就优先使用激活的配置文件,激活的配置文件没有配置的,就使用当前的配置选项。

6.读取自定义配置

在核心配置文件application.properties中添加自定义配置如下:

  1. #自定义配置
  2. boot.name=您好吗
  3. boot.location=青岛李沧区

有两种方式进行读取:

1)使用@Value注解,如下:

  1. /**
  2. * 读取自定义配置方式一
  3. */
  4. @Controller
  5. public class ConfigInfoController {
  6. @Value("${boot.name}")
  7. private String name;
  8. @Value("${boot.location}")
  9. private String location;
  10. @RequestMapping("/boot/config")
  11. public @ResponseBody String config(){
  12. //方式一测试
  13. return name + "---" + location;
  14. }
  15. }

2)使用@ConfigurationProperties,如下:

  1. /**
  2. * 读取自定义配置方式二
  3. */
  4. @Component //使用组件注解
  5. @ConfigurationProperties(prefix="boot")//参数prefix定义配置参数boot.name等的前缀boot
  6. public class ConfigInfo {
  7. private String name;//直接使用参数配置boot.name的name来绑定
  8. private String location;
  9. public String getName() {
  10. return name;
  11. }
  12. public void setName(String name) {
  13. this.name = name;
  14. }
  15. public String getLocation() {
  16. return location;
  17. }
  18. public void setLocation(String location) {
  19. this.location = location;
  20. }
  21. }

访问这两个配置参数变量值,如下:

  1. @Autowired
  2. ConfigInfo configInfo;
  3. @RequestMapping("/boot/config")
  4. public @ResponseBody String config(){
  5. //方式二测试
  6. return configInfo.getName() + "---" + configInfo.getLocation();
  7. }

7.Spring boot下的Spring mvc

主要注意几个注解的使用和含义:

1)@Controller:与之前的Spring mvc的含义和用法一样

2)@RestController:相当于@Controller与@ResponseBody的组合。使用该注解可以免去@ResponseBody的使用,返回Json或字符串。如下:

  1. @RestController //相当于@Controller+@ResponseBody
  2. public class MvcController {
  3. @RequestMapping("/boot/rest")
  4. public Object getUser(){
  5. User user = new User();
  6. user.setId(1000);
  7. user.setName("xudasong");
  8. return user;
  9. }
  10. }

3)@GetMapping:相当于@RequestMapping与get方法的组合,即@RequestMapping(value="/boot/hello", method=RequestMethod.GET)

4)同理,@PostMapping、@PutMapping、@DeleteMapping

8.Spring boot下使用jsp

需要注意的一点:即在pom.xml文件,在<build></build>标签内加上:

  1. <resources>
  2. <resource>
  3. <directory>src/main/webapp</directory>
  4. <targetPath>META-INF/resources</targetPath>
  5. <includes>
  6. <include>**/*.*</include>
  7. </includes>
  8. </resource>
  9. </resources>

否则在Controller种返回jsp页面时会报404错误。

关于jsp页面前缀和后缀的配置,可在核心配置文件application.properties里加上:

  1. spring.mvc.view.prefix=/
  2. spring.mvc.view.suffix=.jsp

9.Spring boot 与Mybatis整合

开发步骤如下:

 在pom.xml下加上maybatis代码自动生成插件,如下:

10.Spring boot 事务支持

使用事务(即出现异常时支持回滚)非常简单:

1)在入口类中使用注解@EnableTransationManagement开启事务支持;

2)在访问数据库的Service方法上添加注解@Transactional即可。

11.Spring boot 实现RestFull主要是几个注解实现

1)@PathVariable

  • 获取url中的数据;
  • 该注解是实现RestFull最主要的一个注解。
  1. @RequestMapping("/boot/user/{id}/name")
  2. public Object user(@PathVariable(id) Integer id,@PathVariable(name) String name){
  3. User user = new User();
  4. user.setId(id);
  5. user.setName(name);
  6. return user;
  7. }
  8. //访问格式:http://localhost:8080/boot/user/106/xudasong

2)增加 post方法

  • 使用PostMapping;
  • 接收和处理Post的请求

3)删除 delete方法

  • DeleteMapping;
  • 接收delete方式的请求,可以使用GetMapping代替

4)修改 put方法

  • PutMapping
  • 接收put方式的请求,可以使用PostMapping代替

5)查询  get方法

  • GetMapping
  • 接收get方式的请求

11.spring boot集成使用Redis

具体步骤如下:

应用实例:

注意

  • 使用时注意将实体类进行序列化,即实现Serializable.
  • spring boot帮我们注入的RedisTemplate类,泛型里面只能写<String, String>、<Object, Object>

上面的实例在高并发条件下会出现缓存穿透的问题,下面是解决这个问题的修改后的:

测试上面的缓存穿透问题的代码(使用多线程):

其中Executors.newFixedThreadPool(25)表示使用线程池开启25个线程。

 

 

二、Spring Cloud

1. Spring提供了一系列工具,可以帮助开发人员迅速搭建分布式系统中的公共组件(比如:配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁,主节点选举, 分布式session, 集群状态)。协调分布式环境中各个系统,为各类服务提供模板性配置。使用Spring Cloud, 开发人员可以搭建实现了这些样板的应用,并且在任何分布式环境下都能工作得非常好,小到笔记本电脑, 大到数据中心和云平台。

具体部署实践可看考这篇博文:随笔分类 - Spring Cloud

2. Spring Cloud开发中遇到的坑

(1)服务调用者在进行调用服务提供者的时候参数始终传递不到服务提供者层(我用的是path路径传参数) ,后来发现是在controller层的方法参数前也要添加@PathVariable,只在接口上添加时不行的。

(2)微服务之间调用传参时,使用@RequestBody传JSON数据时,在@PostMapping括号内必须加入consumes=MediaType.APPLICATION_JSON_UTF8_VALUE,如:

  1. @RequestMapping(value="/api/test,consumes="MediaType.APPLICATION_JSON_UTF8_VALUE)
  2. public void login(@RequestBody LoginRequest request){}

其中,consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html; 还有produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回。

(3)当微服务提供方的API的服务有根路径时,调用方在继承提供方接口的同时需要在@FeignClient注解括号内加入path参数,即context_path,如:

  1. @FeignClient(value="提供方服务名",path="提供方根路径")
  2. public interface TestFeignClient extends TestService{}

(4)微服务使用spring自带的RestTemplate进行微信api的URI请求时,内网访问失败,需加入如下配置:

  1. package com.example.springbootdemo.config;
  2. import org.springframework.cloud.client.loadbalancer.LoadBalanced;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.context.annotation.Primary;
  6. import org.springframework.http.client.ClientHttpRequestFactory;
  7. import org.springframework.http.client.SimpleClientHttpRequestFactory;
  8. import org.springframework.web.client.RestTemplate;
  9. /**
  10. * 用于内网访问外网的REST请求配置
  11. */
  12. @Configuration
  13. public class RestTemplateConfig {
  14. //基于jdk的Spring的RestTemplate
  15. @Bean
  16. @Primary
  17. public RestTemplate restTemplate(ClientHttpRequestFactory factory){
  18. return new RestTemplate(factory);
  19. }
  20. @Bean
  21. public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
  22. SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
  23. factory.setReadTimeout(5000); //ms
  24. factory.setConnectTimeout(5000); //ms
  25. return factory;
  26. }
  27. //基于springcloud的RestTemplate
  28. @LoadBalanced
  29. @Bean
  30. RestTemplate loadBalanced(){
  31. return new RestTemplate();
  32. }
  33. }

(5)微服务多服务注册中心,防止以机器名注册,而以IP进行注册的办法,配置文件需加入如下:

  1. eureka.instance.prefer-ip-address=true
  2. eureka.instance.instance-id=${spring.cloud.client.ip-address}:${server.port}

(6)spring-cloud-dependencies的版本与spring-cloud-starter-openfeign和spring-cloud-starter-netflix-eureka-client的版本是有依赖关系的,要不然版本对应不上feign调用的时候会报错。

 解决办法:

spring-cloud-dependencies版本依赖放在<dependencyManagement>中,即:

  1. <dependencyManagement>
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-dependencies</artifactId>
  5. <version>Finchley.RELEASE</version>
  6. <type>pom</type>
  7. <scope>import</scope>
  8. </dependency>
  9. </dependencies>
  10. </dependencyManagement>

而spring-cloud-starter-openfeign和spring-cloud-starter-netflix-eureka-client两个依赖不要写版本号,maveb会自动根据spring-cloud-dependencies的版本下载相应版本的jar包,同时放在<dependencies>下,即:

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.cloud</groupId>
  8. <artifactId>spring-cloud-starter-openfeign</artifactId>
  9. </dependency>
  10. <dependencies>

(7)spring-boot升到2.1.6版本时启动会报某个.class类已存在的错误,解决办法是在配置文件加上以下一句:

spring.main.allow-bean-definition-overring=true 即当遇到同名字的时候,是否允许覆盖注册

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/243558
推荐阅读
相关标签
  

闽ICP备14008679号