赞
踩
1. Spring Boot简介
Spring boot特点:只使用一个核心配置文件,取消了一系列xml配置,甚至连web.xml都没有, 全部使用注解的方式完成WEB层的功能。框架内置Tomcat服务器,运行启动类中的Main函数即可启动。
它最重要的是以下四个核心:
Spring Boot 具有如下特性:
2. 工程搭建
具体可参考这篇博文:Intellij IDEA 搭建Spring Boot项目
生成的项目中,resources文件夹下,static文件夹下存放静态文件,比如css、js、html和图片等 ;templates下存放html文件,controller默认访问该文件夹下的html文件;这个在application.properties配置文件中是可以修改的。
3. @SpringBootApplication开启了Spring的组件扫描和Spring Boot的自动配置功能。实际上, @SpringBootApplication将三个有用的注解组合在了一起:
4. 使用spring boot+mybatis,使用IntelliJ IDEA开发,记录一些问题的解决方法:
1)在使用@Mapper注解方式代替XXmapper.xml配置文件,使用@Select等注解配置sql语句的情况下,如何配置数据库字段名到JavaBean实体类属性命的自动驼峰命名转换?
使用spring boot后,越来越喜欢用注解方式进行配置,代替xml配置文件方式。mybatis中也可以完全使用注解,避免使用xml方式配置mapper。
设置自动驼峰命名转换,在xml中可以直接配置mapUnderscoreToCamelCase属性。但是使用注解方式时,经过一番查找资料才找到比较好的设置方法。如下:
在spring boot的配置文件application.properties中,加入配置项:
- mybatis.configuration.mapUnderscoreToCamelCase=true
- 或
- mybatis.configuration.map-underscore-to-camel-case=true
设为true表示开启驼峰转换。经过试验,两种配置方法都可以。但如果同时配置,前者mybatis.configuration.mapUnderscoreToCamelCase的优先级更高。
参考:
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的来源。
查找解决方法,找到了这里的问答:
里面提到安装【MyBatis plugin】插件可以解决,但是我尝试安装这个插件并启用后,仍然有红色报错(插件已经激活,不是license导致的问题),所以猜测这个插件可能是只针对XXmapper.xml配置的方式有效,而对@Mapper注解Dao interface的方式无效(针对后一种情况是否有效,大家尝试了可以反馈下结果)。
所以只好采用一种折中的不算完美的办法,在Dao interface中添加@Mapper的同时,再添加@Repository(或者@Component也可以),如下方代码的第1行:
- @Repository
- @Mapper
- public interface UserDao {
-
- @Select("SELECT phone FROM user WHERE name = #{name}") //动态传入表名,可以使用 ...FROM ${tableName}... ,但需要解决sql注入风险
- String getPhoneByUserName(@Param("name") String name);
- }
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中添加自定义配置如下:
- #自定义配置
- boot.name=您好吗
- boot.location=青岛李沧区
有两种方式进行读取:
1)使用@Value注解,如下:
- /**
- * 读取自定义配置方式一
- */
- @Controller
- public class ConfigInfoController {
- @Value("${boot.name}")
- private String name;
-
- @Value("${boot.location}")
- private String location;
-
- @RequestMapping("/boot/config")
- public @ResponseBody String config(){
- //方式一测试
- return name + "---" + location;
- }
- }
2)使用@ConfigurationProperties,如下:
- /**
- * 读取自定义配置方式二
- */
- @Component //使用组件注解
- @ConfigurationProperties(prefix="boot")//参数prefix定义配置参数boot.name等的前缀boot
- public class ConfigInfo {
-
- private String name;//直接使用参数配置boot.name的name来绑定
- private String location;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getLocation() {
- return location;
- }
-
- public void setLocation(String location) {
- this.location = location;
- }
- }
访问这两个配置参数变量值,如下:
- @Autowired
- ConfigInfo configInfo;
-
- @RequestMapping("/boot/config")
- public @ResponseBody String config(){
- //方式二测试
- return configInfo.getName() + "---" + configInfo.getLocation();
- }
7.Spring boot下的Spring mvc
主要注意几个注解的使用和含义:
1)@Controller:与之前的Spring mvc的含义和用法一样
2)@RestController:相当于@Controller与@ResponseBody的组合。使用该注解可以免去@ResponseBody的使用,返回Json或字符串。如下:
- @RestController //相当于@Controller+@ResponseBody
- public class MvcController {
- @RequestMapping("/boot/rest")
- public Object getUser(){
- User user = new User();
- user.setId(1000);
- user.setName("xudasong");
- return user;
- }
- }
3)@GetMapping:相当于@RequestMapping与get方法的组合,即@RequestMapping(value="/boot/hello", method=RequestMethod.GET)
4)同理,@PostMapping、@PutMapping、@DeleteMapping
8.Spring boot下使用jsp
需要注意的一点:即在pom.xml文件,在<build></build>标签内加上:
- <resources>
- <resource>
- <directory>src/main/webapp</directory>
- <targetPath>META-INF/resources</targetPath>
- <includes>
- <include>**/*.*</include>
- </includes>
- </resource>
- </resources>
否则在Controller种返回jsp页面时会报404错误。
关于jsp页面前缀和后缀的配置,可在核心配置文件application.properties里加上:
- spring.mvc.view.prefix=/
- 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
- @RequestMapping("/boot/user/{id}/name")
- public Object user(@PathVariable(id) Integer id,@PathVariable(name) String name){
- User user = new User();
- user.setId(id);
- user.setName(name);
- return user;
- }
-
- //访问格式:http://localhost:8080/boot/user/106/xudasong
2)增加 post方法
3)删除 delete方法
4)修改 put方法
5)查询 get方法
11.spring boot集成使用Redis
具体步骤如下:
应用实例:
注意:
上面的实例在高并发条件下会出现缓存穿透的问题,下面是解决这个问题的修改后的:
测试上面的缓存穿透问题的代码(使用多线程):
其中Executors.newFixedThreadPool(25)表示使用线程池开启25个线程。
1. Spring提供了一系列工具,可以帮助开发人员迅速搭建分布式系统中的公共组件(比如:配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁,主节点选举, 分布式session, 集群状态)。协调分布式环境中各个系统,为各类服务提供模板性配置。使用Spring Cloud, 开发人员可以搭建实现了这些样板的应用,并且在任何分布式环境下都能工作得非常好,小到笔记本电脑, 大到数据中心和云平台。
具体部署实践可看考这篇博文:随笔分类 - Spring Cloud
2. Spring Cloud开发中遇到的坑
(1)服务调用者在进行调用服务提供者的时候参数始终传递不到服务提供者层(我用的是path路径传参数) ,后来发现是在controller层的方法参数前也要添加@PathVariable,只在接口上添加时不行的。
(2)微服务之间调用传参时,使用@RequestBody传JSON数据时,在@PostMapping括号内必须加入consumes=MediaType.APPLICATION_JSON_UTF8_VALUE,如:
- @RequestMapping(value="/api/test,consumes="MediaType.APPLICATION_JSON_UTF8_VALUE)
- public void login(@RequestBody LoginRequest request){}
其中,consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html; 还有produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回。
(3)当微服务提供方的API的服务有根路径时,调用方在继承提供方接口的同时需要在@FeignClient注解括号内加入path参数,即context_path,如:
- @FeignClient(value="提供方服务名",path="提供方根路径")
- public interface TestFeignClient extends TestService{}
(4)微服务使用spring自带的RestTemplate进行微信api的URI请求时,内网访问失败,需加入如下配置:
- package com.example.springbootdemo.config;
-
- import org.springframework.cloud.client.loadbalancer.LoadBalanced;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.context.annotation.Primary;
- import org.springframework.http.client.ClientHttpRequestFactory;
- import org.springframework.http.client.SimpleClientHttpRequestFactory;
- import org.springframework.web.client.RestTemplate;
-
- /**
- * 用于内网访问外网的REST请求配置
- */
- @Configuration
- public class RestTemplateConfig {
-
- //基于jdk的Spring的RestTemplate
- @Bean
- @Primary
- public RestTemplate restTemplate(ClientHttpRequestFactory factory){
- return new RestTemplate(factory);
- }
-
- @Bean
- public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
- SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
- factory.setReadTimeout(5000); //ms
- factory.setConnectTimeout(5000); //ms
- return factory;
- }
-
- //基于springcloud的RestTemplate
- @LoadBalanced
- @Bean
- RestTemplate loadBalanced(){
- return new RestTemplate();
- }
-
- }
(5)微服务多服务注册中心,防止以机器名注册,而以IP进行注册的办法,配置文件需加入如下:
- eureka.instance.prefer-ip-address=true
- 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>中,即:
- <dependencyManagement>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-dependencies</artifactId>
- <version>Finchley.RELEASE</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
- </dependencies>
- </dependencyManagement>
而spring-cloud-starter-openfeign和spring-cloud-starter-netflix-eureka-client两个依赖不要写版本号,maveb会自动根据spring-cloud-dependencies的版本下载相应版本的jar包,同时放在<dependencies>下,即:
- <dependencies>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-openfeign</artifactId>
- </dependency>
- <dependencies>
(7)spring-boot升到2.1.6版本时启动会报某个.class类已存在的错误,解决办法是在配置文件加上以下一句:
spring.main.allow-bean-definition-overring=true 即当遇到同名字的时候,是否允许覆盖注册
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。