IDEA创建项目。
创建项目
添加依赖pom.xml
spring-boot-starter-parent是一个特殊的Stater,提供了一些Maven默认的配置,同时还提供了依赖管理功能。springboot中提供的starter非常多,这些starter主要为第三方库提供自动配置,例如:要开发一个WEB项目,就可以引入一个WEB的Starter.
org.springframework.boot
spring-boot-starter-parent
2.7.1
pom
org.springframework.boot
spring-boot-starter-web
2.7.0
注:spring-boot-starter-parent虽然很方便,但是读者在公司中开发微服务项目或者多模块时一般需要使用公司自已的parent,这个时候如果还想进行项目依敇版本的统一管理,就需要使用dependencyManagement来实现了。添加如下代码:
org.springframework.boot
spring-boot-dependencies
2.2.6
pom
import
此时,就可以不用继承spring-boot-starter-parent了,但是java版本,编码的格式等都需要开发者手动配置。但java版本的配置很简单,添加一个plugin即可:
org.apache.maven.plugins
maven-complier-plugin
3.1
1.8
至于编码格式,如果采用了上述方法创建spring boot项目,那么编码格式默认会加上面;如果是通过普通maven项目配置成的spring boot项目,那么在pom.xml文件中加入如下配置即可:
UTF-8
UTF-8
不过本的配的jdk可在maven构建项目时设定,看settings.xml文件本人电脑,网盘上非常多,都是配好的,只要设置即可,这里不讲那知识。不过jdk是1.8版的,有些老。
启动项目--不用另外安装tomcat
一,编写启动类。
---注解@SpringBootApplication表示开启自动化配置,代替了@EnableAutoConfiguration和@ComponentScan。web项目会自动配置spring和springmvc整合。有了springboot我们再也不用配spring.xml,springmvc.xml文件了。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class,args);
}
}
二,接下来创建一个springMVC中的控制器-HelloController,代码如下
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "hello spring boot!";
}
}
三,启动项目。
《1》使用Maven命令启动
mvn sring-boot:run
《2》直接运行main方法.
《3》,打包,再java -jar xxx.jar,启动项目。
或命行行:
mvc package
四,配置tomcat与定制banner.
<1>----在springboot项目中,可以内置tomcat,jetty,Undertow,Netty等容器。当开发者添加了srping-boot-starter-web后,默认会使用tomcat作为web容器。不过我们可以对web容器进行配置,特别是端口。
---application.properties也可以用YAML配置文件代替。
application.properties可以放在如下图四个位置中,调用优先级高到低1~4.本人此处位置当然是最不好的
server.port=8082
server.error.path=/error
server.servlet.session.timeout=30m
#server.srvlet.context-path=/chapter02 #这里是项目名称,没有则表示为'/',若写上,表示访问时要带上该名字。
server.tomcat.uri-encoding=utf-8
server.tomcat.max-threads=500
#server.tomcat.basedir=/home/sang/tmp
<2>配置banner.
首先:在resources下建一个banner.txt文件。
然后:到一个网站http://www.network-science.de/ascii/
网站中,输入要在项目启动时显示的字,再点do it!.
五,测试
http://localhost:8080/hello
properites配置
---SpringBoot中采用了大量的自动化配置,但是对开发者而言,在寮际项目中不可避免会有一些需要自已手动配置。上面已经介绍了配端口,SSL证书等的配置。
----无论是properties还是YAML(马上讲)配置文件,s最终都会被加载到spring Environment中。spring提供了@Value注解以及@EnvironmentAware接口来将spring Environment中的数据注入到属性上,spring boot 对此进 一步提出了类型安全配置属性(Type-safe Configuration Properties),这样即使在数据量非常大的情况下,也可以更加方便地将配置文件中的数据注入到bean中。
例:
1--application.properties
book.name=三国演义
book.author=罗贯中
book.price=30
2--Book.java
@Component
@ConfigurationProperties(prefix = "book")
public class book {
private String name;
private String author;
private Float price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Float getPrice() {
return price;
}
public void setPrice(Float price) {
this.price = price;
}
@Override
public String toString() {
return "book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
'}';
}
}
2--BookController.java
@RestController
public class BookController {
@Autowired
book book;
@GetMapping("/book")
public String book1(){
return book.toString();
}
}
4--中文乱码处理。
5--测试
https://localhost:8080/book回车
注意:用这里我用了https,因为我用java一个SSL工具生了一个证书 ,详情见‘’-‘域名服务’-‘jdk...’
YAML 配置(JSON超集)功能与properties相似。
YAML简洁强大,是一种专门用来书写配置文件的语言,可以替代properties文件。spring-boot-starter-web依敇间接地引入了snakeyaml依赖,snakeyaml会实现对YAML配置的解析。YAML的使用非常简单,利用缩进来表示层级关系,并且大小写敏感。在springboot项目中使用YAML只需要在resources目录下创建一个xxx.yml文件即可。如:application.yml
server:
port: 80
# servlet:
# context-path: /springbootvue
tomcat:
uri-encoding: utf-8
my:
name: 江南一点雨
address: chian
注意:my不属于server,不能写在server的右边它是一个对象
User.java
@Component
@ConfigurationProperties(prefix = "my")
public class User{
private String name;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
}
这里会把 yml中定义的my对象注入到User属性中。
@RestController
public class UserController {
@Autowired
User user;
@GetMapping("/user")
public String user(){
return user.toString();
}
}
该控制类中,用做测试我们来显示对象的属性值。
http://localhost:80/user回车
这里有一个问题,就是--Java非法字符: ‘\ufeff‘
处理办法:
1.到IDEA右下角,点击GBK,然后按下图点convert.
2.再次类推点击utf-8,再点convert
YAML还支持更复杂的配置,即集合中也可以是一个对象,例:
@Component
@ConfigurationProperties(prefix = "my")
public class Users {
private List users;
get/set/toString()方法;
}
class User{
private String name;
private String address;
private List favorites;
get/set/toString()方法;
}
application.yml
server:
port: 80
servlet:
context-path: /
tomcat:
uri-encoding: utf-8
book:
name: 三国演义
author: 罗惯中
price: 30
favorites:
- 足球
- 图谱
- Coding
my: #复杂的配置
users:
- name: 徐会凤
address: 江西南昌
favorites:
- 足球
- 图谱
- Coding
- name: 熊少文
address: 江西南昌
favorites:
- 吉他
- 对象
- Coding
UserController.java
@RestController
public class UserController {
@Autowired
Users users;
@GetMapping("/users")
public String users(){
return users.toString();
}
}
测试结果:http://localhost/users回车
Book{name='三国演义', author='罗惯中', price=30.0, favorites=[足球, 图谱, Coding]}
-----在spring Boot 中使用YAML虽然方便,但是YAML也有一些缺陷,例如无法使用注解@PropertySource加载YMAL文件,如果项目中有这种需求,还是需要使用Properties 格式的配置文件。
profile切换环境,如生产环境与测试环境,一个80端口,一个8080端口
首先:::在resources下创建两个文件 application-dev.properties,application-prod.properties。
其次:::在两个文件中加如下代码.
server.port=8080
server.port=80
server.error.path=/error
server.servlet.session.timeout=30m
server.tomcat.uri-encoding=utf-8
server.tomcat.max-threads=500
server.ssl.key-store=sang.pl2
server.ssl.key-alias=tomcathttps
server.ssl.key-store-password=123456
book.name=三国演义
book.author=罗惯中
book.price=30
最后:::在主文件中application.properties中加如下代码.
spring.profiles.active=dev
Spring Boot整合视图层技术。
---在目前的企业级应用开发中, 前后端分离是趋势,但是视图层技术还占有一席之地。Spring boot对视图层技术提供了很好的支持。官方推荐使用的模板引擎是Thymeleaf,不过FreeMarker也支持,JSP技术在这里不推荐使用。
- Thymeleaf
pom.xml导入的依赖包
org.springframework.boot
spring-boot-starter-thymeleaf
----由此配置可以看到,默认的模板位置在classpath:/templates/,默认的模板后缀为.html.当然,如果开发者相对默认的配置参数进行自定义配置,那么可以在application.properties中进行配置.部分配置如下。
#Thymeleaf配置
#是否开启缓存,开发时可以设置为false,默认为true
spring.thymeleaf.cache=true
#检查模板是否存在,默认为true
spring.thymeleaf.check-template=true
#检查模板位置是否存在,默认为true
spring.thymeleaf.check-template-location=true
#模板文件编码
spring.thymeleaf.encoding=UTF-8
#模板文件位置
spring.thymeleaf.prefix=classpath:/templates/
#Content-Type配置
spring.thymeleaf.servlet.content-type=text/html
#模板文件后缀
spring.thymeleaf.suffix=.html
举例:我用ModelAndView对象的addObject("xxx",xxx)封装两个书本对象,通过返回给web页显示
1.bean--Book2.java
public class Book2 {
private Integer id;
private String name;
private String author;
get/set/toString()方法;
}
2.BookController.java
@GetMapping("/books")
public ModelAndView books(){
List books = new ArrayList<>();
Book2 b1=new Book2();
b1.setId(1);
b1.setName("三国演义");
b1.setAuthor("罗贯中");
Book2 b2 =new Book2();
b2.setId(2);
b2.setName("红楼梦");
b2.setAuthor("曹雪琴");
books.add(b1);
books.add(b2);
ModelAndView mv =new ModelAndView();
mv.addObject("books",books);
return mv;
}
3.resources---templates--books.html
Books List
图书编号
图书名称
图书作者
4.测试:http://localhost:80/books回车
图书编号 图书名称 图书作者
1 三国演义 罗贯中
2 红楼梦 曹雪琴
- 整合FreeMarker
导包
org.springframework.boot
spring-boot-starter-freemarker
- Freemarker
--------这个是很古老的模板引擎。应用参考 '点餐系统‘。这里只给一个配置文件的代码。
#Freemarker配置
#HttpServletRequest的属性是否可以覆盖controller中model的同名项
spring.freemarker.allow-request-override=false
#HttpSession的属性是否可以覆盖controller中model的同名项
spring.freemarker.allow-session-override=false
spring.freemarker.cache=true
spring.freemarker.charset=UTF-8
spring.freemarker.content-type=text/html
spring.freemarker.expose-request-attribute=false
spring.freemarker.expose-session-attribute=false
spring.freemarker.suffix=.ftl
spring.freemarker.template-loader-path=classpath:/templates/
spring boot整合web开发
- 返回JSON数据。
----JSON是目前主流的前后端数据传输方式,Spring MVC 中使用消息转换器HttpMessageConverter对JSON的转换提供了很好的支持,在Spring Boot中更进一步,对相关配置做了更进一步的简化。默认情况下,当开发者创建一个项目后,添加WEB依赖,代码下,这个依赖中默认加入了jackson-databind作为JSON处理器,此时不需要添加额外的JSON处理器就能返回一段JSON了。
org.springframework.boot
spring-boot-starter-web
举例:下面返回BookJson.java的bean对象数据
BookJson.java
import java.util.Date;
public class BookJson {
private String name;
private String author;
@JsonIgnore
private Float price;
@JsonFormat(pattern="yyyy-MM-dd")
private Date publicationDate;
get/set/toString()方法;
}
BookController.java
/**
* 测试返回json数据
* @return BookJson
*/
@GetMapping(value="/bookjson",produces="application/json;charset=UTF-8")
@ResponseBody //这里可以不写。
public BookJson bookjson(){
BookJson book = new BookJson();
book.setAuthor("熊少文");
book.setName("javaspring");
book.setPrice(30f);
book.setPublicationDate(new Date());
return book;
}
---没有produces的设置,会中文乱码。
测试:http://localhost:8080/bookjson
{"name":"javaspring","author":"熊少文","publicationDate":"2022-08-06"}
spring boot自带json格式处理总结:
---如果采用这种方式,那么对于字段忽略,日期格式等常见需求都要通过注解来解决,spring中默认提供MappingJackson2HttpMessageConverter实现转换json格式。当然了,开发者可以根据实际需求自定义转换器。
自定义JSON转换器
一。Gson处理器。
-----Gson是谷歌的一个开源JSON解析框架。使用Gson,需先去除默认的jackson-databind.再添加Gson依赖。
org.springframework.boot
spring-boot-starter-web
com.fasterxml.jackson.core
jackson-databind
com.google.code.gson
gson
测试:https://xiongshaowen.club:80/bookjson
{"name":"javaspring","author":"熊少文","price":30.0,"publicationDate":"Aug 6, 2022 1:30:21 PM"}
---自定义转换格式
----上面的日期太长了,也不符合习惯,这是我们可自定义。Spring boot中提供了Gson的自动转换类GsonHttpMessageConvertersConfiguration,因此Gson的依敇添加成功后,可以像使用springboot自带的jackson-databind那样使用。但是在Gson进行转换时,如果想对日期数据进行格式化,那么还需要开发者自定义HttpMessageConverter.自定义HttpMessageConverter可以通过如下方式。
首先:::看GsonHttpMessageConvertersConfiguration类的Gson转换代码:
@Bean
@ConditionalOnMissingBean
GsonHttpMessageConverter gsonHttpMessageConverter(Gson gson) {
GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
converter.setGson(gson);
return converter;
}
@ConditionalOnMissingBean注解表示当项目中没有提供GsonHttpMessageConverter时才会使用默认的GsonHttpMessageConverter,所以开发者只需要提供一个GsonHttpMessageConverter即可。代码如下:
@Configuration
public class GsonConfig {
@Bean
GsonHttpMessageConverter gsonHttpMessageConverter(){
GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
GsonBuilder builder=new GsonBuilder();
builder.setDateFormat("yyyy-MM-dd");
builder.excludeFieldsWithModifiers(Modifier.PROTECTED);
Gson gson = builder.create();
converter.setGson(gson);
return converter;
}
}
然后:::测试:https://xiongshaowen.club:80/bookjson
日期已经格式化了。
二。fastjson
---fastjson是阿里巴巴一个开源JSON解析框架,是目前JSON解析速度最快的开源框架,该框架也可以集成到Spring Boot中。不同于Gson,fastjson继承完成之后并不能立马生效,需要开发者提供相应的HttpMessageConverter后才能使用,集成fastjson的步子如下:
首先:::除去jackson-databind依赖,引入fastjson依赖。
com.alibaba
fastjson
1.2.47
然后:::配置fastjson的HttpMessageConverter:随便在那个包中写如下代码。
package cn.xiong.com.bean;
@Configuration
public class MyFastJsonConfig {
@Bean
FastJsonHttpMessageConverter fastJsonHttpMessageConverter(){
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
FastJsonConfig config = new FastJsonConfig();
config.setDateFormat("yyyy-MM-dd");
config.setCharset(Charset.forName("UTF-8"));
config.setSerializerFeatures(
SerializerFeature.WriteClassName,
SerializerFeature.WriteMapNullValue,
SerializerFeature.PrettyFormat,
SerializerFeature.WriteNullListAsEmpty,
SerializerFeature.WriteNullStringAsEmpty
);
converter.setFastJsonConfig(config);
return converter;
}
}
代码概述:7~15行分别配置了JSON解析过程的一些细节,例如日期格式,数据编码,是否在生成的JSON中输出类名,是否输出value为null的数据,生成的JSON格式化,空集合输出[]而非null,空字符串输出“”而非null等基本配置。
再后:::在application.properties文件中配置一下响应编码,否则返回的JSON中文会乱码。
spring.http.encoding.force-response=true
对于 FastJsonHttpMessageConverter的配置,除了上面这种方式之外,还有另一种方式。在spring boot项目中,当开发者引入spring-boot-starter-web依赖之后,该依赖又依赖了spring-boot-autoconfigure,在这个自动化配置中,有一个WebMvcAutoConfiguration类提供了对Spring MVC最基本的配置,如果某一项自动配置不满足开发需求,开发者可以针对该项自定义配置,只需要实现WebMvcConfigurer接口即可(在spring 5.0之前是通过继承WebMvcConfigurerAdapter类来实现的)。代码如下:
@Configuration
class MyWebMvcConfig implements WebMvcConfigurer{
@Override
public void configureMessageConverters(List> converters){
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
FastJsonConfig config = new FastJsonConfig();
config.setDateFormat("yyyy-MM-dd");
config.setCharset(Charset.forName("UTF-8"));
config.setSerializerFeatures(
SerializerFeature.WriteClassName,
SerializerFeature.WriteMapNullValue,
SerializerFeature.PrettyFormat,
SerializerFeature.WriteNullListAsEmpty,
SerializerFeature.WriteNullStringAsEmpty
);
converter.setFastJsonConfig(config);
converters.add(converter);
}
}
测试结果如下:
- 静态资源访问
----在spring MVC中,对于静态资源都需要开发者手动配置静态资源过滤。Spring boot中对此也提供了自动化配置,可以简化静态资源过滤配置。
spring boot中对于spring mvc的自动化配置都在WebMvcAutoConfiguration类中,因此对于默认的静态资源过滤策略可以从这个类中一窥究竟。
在WebMvcAutoConfiguration类中有一个静态内部类WebMvcAutoConfigurationAdapter实现了1中提到的WebMvcConfigurer接口,该接口中有一个方法addResourceHandlers,是用来配置静态资源过滤的。方法在WebMvcAutoConfigurationAdapter类中得到了实现,部分代码如下:
public void addResourceHandlers(ResourceHandlerRegistry registry) {
................
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
this.customizeResourceHandlerRegistration(registry.
addResourceHandler(new String[]{staticPathPattern}).
addResourceLocations(WebMvcAutoConfiguration.
getResourceLocations(this.resourceProperties.getStaticLocations())).
setCachePeriod(this.getSeconds(cachePeriod)).
setCacheControl(cacheControl));
}
}
}
Spring boot在这里进行了默认的静态资源过滤配置,其中staticPathPattern默认定义在WebMvcProperties中构造方法中,定义如下:
private String staticPathPattern = "/**";
this.resourceProperties.getStaticLocations()获取到的默认静态资源位置定义在ResourceProperties中代码如下:
private static final String[] CLASSPATH_RESOURCE_LOCATIONS =
new String[]{"classpath:/META-INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/"};
private String[] staticLocations;
private boolean addMappings;
private final ResourceProperties.Chain chain;
private final ResourceProperties.Cache cache;
public ResourceProperties() {
this.staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
.....................
在getResourceLocations方法中,对这4个静态资源位置做了扩充,代码如下:
static String[] getResourceLocations(String[] staticLocations) {
String[] locations = new String[staticLocations.length + SERVLET_LOCATIONS.length];
System.arraycopy(staticLocations, 0, locations, 0, staticLocations.length);
System.arraycopy(SERVLET_LOCATIONS, 0, locations, staticLocations.length, SERVLET_LOCATIONS.length);
return locations;
}
其中SERVLET_LOCATIONS的定义是一个{"/"}.
------综上所述:spring boot默认会过滤所有的静态资源,而静态资的位置一共有5个,分别是"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/","/",也就是说,开发发者可以将静态资源放到这5个位置中的任总一个。注意,按照定义的顺序,5个静态资源位置的优先级依次降低。但是一般情况下,spring boot项目不需要webapp目录,所以"/"可以不考虑,一般创建项目时,默认static为静态资源的目录。
***测试:http://localhost:80/1.jpeg
自定义过滤静态资源策略application.properties或yml文件中
#定义静态资源过滤策略
spring.mvc.static-path-pattern=/static/**
spring.resources.static-locations=classpath:/static/
........classpath表示根的resources目录。
***测试:http://localhost:80/static/1.jpeg
- 文件上传
Spring MVC对文件上传做了个简化,在spring boot中对此做了更进一步简化,文件上传更为方便。
----java中的文件上传一共涉及两个组件,一个是CommonsMultipartResolver,另一个是StandardServletMultipartResolver.其中CommonsMultipartResolver使用commons-fileupload来处理multipart请求,而StandardServletMultipartResolver则是基于servlet 3.0来处理multipart请求的,因此若使用StandardServletMultipartResolver,则不需要添加额外的jar包,tomcat7.0开始京支持servlet 3.0,而spring boot 2.x内套了Tomcat 8.5.32,因此可以直接使用StandardServletMultipartResolver。而在spring boot提供的文件上传自动化配置类MultipartAutoConfiguration中,默认也是采用StandardServletMultipartResolver,部分代码如下:
@ConditionalOnMissingBean({MultipartResolver.class})
public StandardServletMultipartResolver multipartResolver() {
StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();
multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily());
return multipartResolver;
}
---根据这里的配置可以看出,如果开发者没有提供MultipartResolver,那么默认采用的MultipartResolver就是StandardServletMultipartResolver。因此,在spring boot中上传文件甚至可做到零配置。
一。单文件上传
首先:创建一个springboot项目并添加spring-boot-starter-web依赖。
然后:在resources目录下的static目录中创建一个upload.html内容如下
上传文件
再然后:在项目中创建一个控制类 FileUploadController.java
@RestController
public class FileUploadController {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
@PostMapping("/upload")
public String upload(MultipartFile uploadFile, HttpServletRequest req){
String realPath=req.getSession().getServletContext().getRealPath("\\uploadFile/");
//getRealPath: C:\Users\Administrator\AppData\Local\Temp\tomcat-docbase.8080.596262946748719422/uploadFile/
System.out.println("getRealPath: "+realPath);
String format=sdf.format(new Date());
File folder = new File(realPath);
if(!folder.isDirectory()){
folder.mkdir();
}
String oldName = uploadFile.getOriginalFilename();
String newName = UUID.randomUUID().toString()+oldName.substring(oldName.lastIndexOf("."),oldName.length());
try{
uploadFile.transferTo(new File(folder,newName));
String filePath=req.getScheme()+"://"+req.getServerName()+":"+req.getServerPort()+"/uploadFile/"+format+newName;
return filePath;
} catch (IOException e) {
e.printStackTrace();
}
return "上传失败";
}
}
最后测试:http://localhost:8080/upload.html
--------------选择一个文件上传后:
网页显示如下示例:(每次上传都会改变)
http://localhost:8080/uploadFile/2023/02/27e79003eb-72f7-49c2-b69d-8e6aa85a632e.htm
全局配置文件中的一些配置
spring.servlet.multipart.enabled=true
#是否开启文件上传支持
spring.servlet.multipart.file-size-threshold=0
#表示写入磁盘的阀值
spring.servlet.multipart.location=Z:\\temp
spring.servlet.multipart.max-file-size=18MB
spring.servlet.multipart.max-request-size=18MB
spring.servlet.multipart.resolve-lazily=false
- CORS支持
----CORS(Cross-Origin Resource,Sharing)是由W3C制定的一种跨域资源共享技术标准,其目就是为了解决前端的跨域请求。在JAVA EE开发中,最常 见的前端跨域请求解决方案是JSONP,但是JSONP只支持GET请求。
----CORS中的GET请求为示例
首先:当浏览器发起请求时,请求中携带了如下信息
...
HOST:localhost:8080
Origin:http://localhost:8081
Referer:http://localhost:8081/index.html
...
然后:假如服务器支持CORS,则服务器给出的响应信息如下:
...
Access-Control-Allow-Origin:http://localhost:8081
Content-Length:20
Content-Type:text/plain;charset=UTF-8
Date:Thu,12,Jul 2022 12:51:14 GMT
...
----响应头有一个Access-Control-Allow-Origin字段,用来记录可以访问该资源的域,当浏览器收到这样的响应头信息后,提取出Access-Control-Allow-Origin字段中的值,发现该值包含当前页面所在的域,就知道这个跨域是被允许的,因此就不再对前端的跨域请求进行限制。
---以DELETE请求为例,当前端发起一个DELETE请求时,这个请求的处理会经过两个步聚
第一步,发送一个OPTIONS 请求,代码如下:
Access-Control-Request-Method DELETE
Connection keep-alive
Host localhost:8080
Origin http://localhost:8081
-----这个请求将向服务器端询问是否具备该资源的DELETE权限,服务端会给前端一个响应,代码如下:
HTTP/1.1 200
Access-Control-Allow-Origin: http://localhost:8081
Access-Control-Allow-Method: DELETE
Access-Control-Max_Age:1800
Allow:GET,HEAD,POST,PUT,DELETE,OPTIONS,PATCH
Content-Length:0
Date: Thu,12 Jul 2022 13:20:26 GMT
第二步:发送DELETE请求,接下来浏览器就会发送一个跨域的DELETE请求,代码如下:
Host: localhost:8080
Origin: http://localhost:8081
Connection: keep-alive
-----服务器给一个响应
HTTP/1.1 200
Access-Control-Allow-Origin: http://localhost:8081
Content-Type: text/plain;charset=UTF-8
Date: Thu,12 Jul 2022 13:20:26 GMT
示例:两个项目cors,cors2同时启 动。cors中默认端口8080作为后台,域为8080, cors2中设端口号为8081,作为前端,他会在index.html的ajax方法中访问不同域的cors后台
------两个项目的pom.xml都一样,只导入web启动器
首先:cors 项目下的 org.sang包下两个文件
-------------------------------------------------------------BookController.java------------------------------------------------------
@RestController
@RequestMapping("/book")
public class BookController {
@PostMapping("/")
// @CrossOrigin(value = "http://localhost:8081"
// ,maxAge = 1800,allowedHeaders = "*")
public String addBook(String name) {
return "receive:" + name;
}
@DeleteMapping("/{id}")
// @CrossOrigin(value = "http://localhost:8081"
// ,maxAge = 1800,allowedHeaders = "*")
public String deleteBookById(@PathVariable Long id) {
return String.valueOf(id);
}
}
//注:注释掉的是注解方式做跨域配置,如果用了注解的,下面的配类就不用了
----------------------------------------------------------------MyWebMvcConfig.java-------------------------------------------------
@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/book/**")
.allowedHeaders("*")
.allowedMethods("*")
.maxAge(1800)
.allowedOrigins("http://localhost:8081");
}
}
//addMapping表示对哪种格式的请求路径进行跨域处理,maxAge表示有效期过后,再次请求,单位秒
然后:cors2项目中,全局配置文件中设端口号8081,再在templates/static/下建一个index.html,放置一个jquery3.3.1.js
-----------------------------------------------------------------Cors2Application.java-------------------------------------------------
server.port=8081
--------------------------------------------------------------------index.html--------------------------------------------------------------
Title
最后:测试
http://localhost:8081/index.html回车,ajax会转域访问8080后台,选‘获取数据’和‘删除数据’会面页面显示:
- 设置系统启动时初始化一些东西
----有一些特殊的任务需要在系统启动时执行,例如配置文件加载,数据库初始化等操作。没有Springboot时,可以在Listener中解决。而springboot提供了两个方案:CommandLineRunner和ApplicationRunner.
一,CommandLineRunner
--------项目启动时会遍历所有CommandLineRunner的实现类并调用其中的run方法,如果系统中有多个CommandLineRunner实现类,可能用注解@Order(x),x数字,对这些类的调用顺序进行排序,数字越小,越先执行。如下代码是两个实现类:
@Component
@Order(3)
public class MyCommandLineRunner1 implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("Runner1>>>"+Arrays.toString(args));
}
}
---------------------------------------------------------------------------------------------------------------------------------------------
@Component
@Order(2)
public class MyCommandLineRunner2 implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("Runner1>>>"+Arrays.toString(args));
}
}
注意:args参数由系统设置提借数值,其设置如下
首先:点击‘Edit Configurations'
然后:找到’program arguments:项。IDEA 2020后在‘Enviroment’选项尗中。
其后:输入值,这里我们输入:“三国演义 罗贯中dddddd”。
最后:启动项目,在控制台中可以看到
2023-03-06 14:10:14.317 INFO 7892 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2023-03-06 14:10:14.319 INFO 7892 --- [ main] org.sang.CommandlinerunnerApplication : Started CommandlinerunnerApplication in 1.251 seconds (JVM running for 1.67)
Runner2>>>[三国演义, 罗贯中dddddd]
Runner1>>>[三国演义, 罗贯中dddddd]
二,ApplicationRunner
@Component
@Order(2)
public class MyApplicationRunner1 implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
List nonOptionArgs = args.getNonOptionArgs();
System.out.println("1-nonOptionArgs>>>" + nonOptionArgs);
Set optionNames = args.getOptionNames();
for (String optionName : optionNames) {
System.out.println("1-key:" + optionName + ";value:" +
args.getOptionValues(optionName));
}
}
}
-----------------------------------------------------------------------------------------------------------------------------------------------
@Component
@Order(1)
public class MyApplicationRunner2 implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
List nonOptionArgs = args.getNonOptionArgs();
System.out.println("2-nonOptionArgs>>>" + nonOptionArgs);
Set optionNames = args.getOptionNames();
for (String optionName : optionNames) {
System.out.println("2-key:" + optionName + ";value:" +
args.getOptionValues(optionName));
}
}
}
----------------------------------------------------------------------结果-------------------------------------------------------------------
2023-03-06 14:27:37.724 INFO 2616 --- [ main] org.sang.CommandlinerunnerApplication : Started CommandlinerunnerApplication in 1.326 seconds (JVM running for 1.761)
2-nonOptionArgs>>>[三国演义, 罗贯中]
1-nonOptionArgs>>>[三国演义, 罗贯中]
注:ApplicationArguments参数的getOptionNames()可能获取入口类中main方法中args接收到的参数。
getOptionValues(optionName)获取args参数的值
----Liunx平台中,我们可以这样设置参数
首先:打包项目。
mvn package
然后:进入打包目录中
....target>java -jar commandlinerunner-0.0.1-SNAPSHOT.jar --name=Michael --age=99 测系统 承担
-------------------------------------------------------------------结果----------------------------------------------------------------------
2-nonOptionArgs>>>[测系统, 承担]
2-key:name;value:[Michael]
2-key:age;value:[99]
1-nonOptionArgs>>>[测系统, 承担]
1-key:name;value:[Michael]
1-key:age;value:[99]
- 路径映身即不通过控制器类映射到某网页上,这样可以增加访问速度
-----假设现在有两个thymeleaf模板的页面login.html,index.html
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.addViewController("/index").setViewName("index");
}
}
测试:直接输入:http://localhost:8080/login或http://localhost:8080/index
进入相关页面,页不需要通过控制器类,这样会加快访问速度。
- 配置AOP(面向切面编程Asepct-Oriented Programming)
-----我们假设这样一个场景:公司有一个人力资源管理系统已经上线,但是系统运行不稳定,有时运行的慢,为了检测出到底是哪个环节出问题了,开发人员想要监控每个方法的执行时间,再根据这些运行时间判断问题所在。当问题解决掉再去除这些监控。如果能在系统运行时动态添加监控代码,就能很好解决问题,这京是面向切面编程的思路。
Jointpoint 连接点: 里面可以被增强的方法即为连接点,如切面类里的所有方法。
Pointcut 切入点: 对Jointpoint进行拦截的定义即为切入点,如拦截所有Service下的所有方法,这个定义即为切入点
Advice 通知: 拦截后要做的事,即为通知----前置,后置,异常,最终等通知。
Aspect 切面: Pointcut和Advice的综合
Target 目标对象: 要增强的类称为Target.
--------下面开始举例:切面切入点是,service层下所有类的方法,监控各方法是否有异常,执行时间结束时间等再输出到控制台显示
一。导入依赖包
org.springframework.boot
spring-boot-starter-aop
二。编写切面类
LogAspect.java
@Component
@Aspect
public class LogAspect {
@Pointcut("execution(* org.sang.aop.service.*.*(..))")
public void pc1() {
}
@Before(value = "pc1()")
public void before(JoinPoint jp) {
String name = jp.getSignature().getName();
System.out.println(new Date());
System.out.println(name + "方法开始执行...");
}
@After(value = "pc1()")
public void after(JoinPoint jp) {
String name = jp.getSignature().getName();
System.out.println(new Date());
System.out.println(name + "方法执行结束...");
}
@AfterReturning(value = "pc1()", returning = "result")
public void afterReturning(JoinPoint jp, Object result) {
String name = jp.getSignature().getName();
System.out.println(name + "方法返回值为:" + result);
}
@AfterThrowing(value = "pc1()",throwing = "e")
public void afterThrowing(JoinPoint jp,Exception e) {
String name = jp.getSignature().getName();
System.out.println(name+"方法抛异常了,异常是:"+e.getMessage());
}
@Around("pc1()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
return pjp.proceed();
}
}
UserService.java
@Service
public class UserService {
public String getUserById(Integer id) {
System.out.println("get...");
User user=new User(1,"xiongshaowen","123456");
return user.toString();
}
public void deleteUserById(Integer id) {
int i = 1 / 0;
System.out.println("delete...");
}
}
User.java
public class User {
private Integer id;
private String username;
private String address;
public User() {
}
public User(Integer id, String username, String address) {
this.id = id;
this.username = username;
this.address = address;
}
//省略getter/setter/toString()方法
UserController.java
@RestController
public class UserController {
@Autowired
UserService userService;
@GetMapping("/getUserById")
public String getUserById(Integer id) {
return userService.getUserById(id);
}
@GetMapping("/deleteUserById")
public void deleteUserById(Integer id) {
userService.deleteUserById(id);
}
}
测试:localhost:8080/getUserById和localhost:8080/deleteUserById
出现如下所示的结果
getUserById方法开始执行...
get...
Mon Mar 06 15:59:42 CST 2023
getUserById方法执行结束...
getUserById方法返回值为:User{id=1, username='xiongshaowen', address='123456'}
----------------------------------------------------------------------------------------------------------------------------------------------
Mon Mar 06 16:04:18 CST 2023
deleteUserById方法开始执行...
Mon Mar 06 16:04:18 CST 2023
deleteUserById方法执行结束...
deleteUserById方法抛异常了,异常是:/ by zero
2023-03-06 16:04:18.918 ERROR 8248 --- [nio-8080-exec-1]
- 自定义favicon
----------favicon是浏览器左上角的图标。可以放在静态资源static路径下或者类路径下,静态的高于类的。
可以使用在线转换网站https://jinaconvert.com/cn/convert-to-ico.php
将一张图片转换成图标,命名为favicon.ico,再放到static下。再启动项目,即可看到该图标。
数据库操作--springboot整合持久层技术
- 整合JdbcTemplate
JdbcTemplate是Spring提供的一套JDBC模板框架,利用AOP技术来解决直接使用JDBC时大量重复代码的问题。它没有mybatis灵活,也没有JPA方便,但比JPA灵活,更比JDBC灵活。
----springboot中对JdbcTemplate的使用提供了自动化配置类JdbcTemplateConfiguration,从它的源码中可以看出,当classpath下存在DataSource和JdbcTemplate并且DataSource只有一个实例时,自动化配置才会生效,若开发者没有提供JdbcOperations,则springboot会自动向容器中注入一个JdbcTemplate(JdbcTemplate是JdbcOperations的子类)。由此可以看到开发者只提供JdbcTemplate的依赖和DataSource依赖即可使用JdbcTemplate。
1-建立数据库chapter05-1与表book,并且插入一些数据
CREATE DATABASE IF NOT EXISTS `chapter05-1` DEFAULT CHARACTER SET utf8
USE `chapter05-1`;
DROP TABLE IF EXISTS `book`;
CREATE TABLE `book` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(128) DEFAULT NULL,
`author` varchar(64) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
insert into `book`(`id`,`name`,`author`) values (1,'三国演义','罗贯中'),(2,'水浒传','施耐奄');
2-创建springboot项目,并导入如下包(当然了web包不用说了),加入了连接池依赖包(阿里的)
org.springframework.boot
spring-boot-starter-jdbc
com.alibaba
druid-spring-boot-starter
1.1.10
mysql
mysql-connector-java
runtime
3.数据库配置applicatin.properties,
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.username=root
spring.datasource.password=xiong
spring.datasource.url=jdbc:mysql://124.222.48.147:3306/chapter05-1
4-创建实体类Book.java
public class Book {
private Integer id;
private String name;
private String author;
//省略setter/getter/toString方法
5-创建dao与service类,dao类中可以注入由spring-jdbc依赖注册到spring容器中的JdbcTemplate代理对象
@Repository
public class BookDao {
//@Autowired
JdbcTemplate jdbcTemplate;
public int addBook(Book book) {
return jdbcTemplate.update("INSERT INTO book(name,author) VALUES (?,?)",
book.getName(), book.getAuthor());
}
public int updateBook(Book book) {
return jdbcTemplate.update("UPDATE book SET name=?,author=? WHERE id=?",
book.getName(), book.getAuthor(), book.getId());
}
public int deleteBookById(Integer id) {
return jdbcTemplate.update("DELETE FROM book WHERE id=?", id);
}
public Book getBookById(Integer id) {
return jdbcTemplate.queryForObject("select * from book where id=?",
new BeanPropertyRowMapper<>(Book.class), id);
}
public List getAllBooks() {
return jdbcTemplate.query("select * from book",
new BeanPropertyRowMapper<>(Book.class));
}
}
-----------------------------------------------------------BookService.java-------------------------------------------------------------
@Service
public class BookService {
@Autowired
BookDao bookDao;
public int addBook(Book book) {
return bookDao.addBook(book);
}
public int updateBook(Book book) {
return bookDao.updateBook(book);
}
public int deleteBookById(Integer id) {
return bookDao.deleteBookById(id);
}
public Book getBookById(Integer id) {
return bookDao.getBookById(id);
}
public List getAllBooks() {
return bookDao.getAllBooks();
}
}
6-控制类
@RestController
public class BookController {
@Autowired
BookService bookService;
@GetMapping("/bookOps")
public void bookOps() {
Book b1 = new Book();
b1.setId(99); //增加记录时,setId不起作用,因为表中设置了id自增。
b1.setName("西厢记");
b1.setAuthor("王实甫");
int i = bookService.addBook(b1);
System.out.println("addBook>>>" + i);
Book b2 = new Book();
b2.setId(1); //下面修改有作用的。
b2.setName("朝花夕拾");
b2.setAuthor("鲁迅");
int updateBook = bookService.updateBook(b2);
System.out.println("updateBook>>>"+updateBook);
Book b3 = bookService.getBookById(1);
System.out.println("getBookById>>>"+b3);
int delete = bookService.deleteBookById(2);
System.out.println("deleteBookById>>>"+delete);
List allBooks = bookService.getAllBooks();
System.out.println("getAllBooks>>>"+allBooks);
}
}
-------------------------------------------------------------------------------控制台-------------------------------------------------------
addBook>>>1
updateBook>>>1
getBookById>>>Book{id=1, name='朝花夕拾', author='鲁迅'}
deleteBookById>>>1
getAllBooks>>>[Book{id=1, name='朝花夕拾', author='鲁迅'}, Book{id=3, name='西厢记', author='王实甫'}]
7-测试http://localhost:8080/bookOps
8-多数据源,下面建两个数据源,我由于条件限制,两个源是同种数据库mysql
首先:数据源起不同的名字--在config层写代码
@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties("spring.datasource.one")
DataSource dsOne() {
return DruidDataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties("spring.datasource.two")
DataSource dsTwo() {
return DruidDataSourceBuilder.create().build();
}
}
当找不到一个匹配的 Bean 时,Spring 容器将抛BeanCreationException 异常,并指出必须至少拥有一个匹配的 Bean。Spring 允许我们通过 @Qualifier 注释指定注入 Bean 的名称,这样歧义就消除了,可以通过下面的方法解决异常。
@Configuration
public class JdbcTemplateConfig {
@Bean
JdbcTemplate jdbcTemplateOne(@Qualifier("dsOne") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
@Bean
JdbcTemplate jdbcTemplateTwo(@Qualifier("dsTwo") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
然后:全局配置文件中,配两个数据源连接
# 数据源1
spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.one.username=root
spring.datasource.one.password=xiong
spring.datasource.one.url=jdbc:mysql://124.222.48.147:3306/chapter05-1
# 数据源2
spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.two.username=root
spring.datasource.two.password=xiong
spring.datasource.two.url=jdbc:mysql://124.222.48.147:3306/chapter05-1
最后:控制类测试
@RestController
public class BookController {
@Resource(name = "jdbcTemplateOne")
// @Autowired
JdbcTemplate jdbcTemplateOne;
@Autowired
@Qualifier("jdbcTemplateTwo")
JdbcTemplate jdbcTemplateTwo;
@GetMapping("/test1")
public void test1() {
List books1 = jdbcTemplateOne.query("select * from book",
new BeanPropertyRowMapper<>(Book.class));
List books2 = jdbcTemplateTwo.query("select * from book",
new BeanPropertyRowMapper<>(Book.class));
System.out.println("books1:"+books1);
System.out.println("books2:"+books2);
}
}
- springboot整合mybatis
1-导包
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.2
---------------
src/main/java
**/*.xml
src/main/resources
------
注意:
2-实体类,库表与上例一样
3-创建数据库访问层dao,service层
BookMapper.java接口
@Mapper
public interface BookMapper {
int addBook(Book book);
int deleteBookById(Integer id);
int updateBookById(Book book);
Book getBookById(Integer id);
List getAllBooks();
}
BookMapper.xml
INSERT INTO book(name,author) VALUES (#{name},#{author})
DELETE FROM book WHERE id=#{id}
UPDATE book set name=#{name},author=#{author} WHERE id=#{id}
BookService.java
@Service
public class BookService {
@Autowired
BookMapper bookMapper;
public int addBook(Book book) {
return bookMapper.addBook(book);
}
public int updateBook(Book book) {
return bookMapper.updateBookById(book);
}
public int deleteBookById(Integer id) {
return bookMapper.deleteBookById(id);
}
public Book getBookById(Integer id) {
return bookMapper.getBookById(id);
}
public List getAllBooks() {
return bookMapper.getAllBooks();
}
}
BookController.java
与上例一模一样,仅供测试
- 整合jpa
-----------参考springboot基础二
,在这里我只是列出几个知识点,那里没有提到。
1-@Transient放到javabean的属性上时,表时,该字段不在创建表时创建对应的列。
2-BookDao.java接口可写sql语句,service实现类中可以查询页数,记录数,如下
public interface BookDao extends JpaRepository{
List getBooksByAuthorStartingWith(String author);
List getBooksByPriceGreaterThan(Float price);
@Query(value = "select * from t_book where id=(select max(id) from t_book)",nativeQuery = true)
Book getMaxIdBook();
@Query("select b from t_book b where b.id>:id and b.author=:author")
List getBookByIdAndAuthor(@Param("author") String author, @Param("id") Integer id);
@Query("select b from t_book b where b.id2 and b.name like %?1%")
List getBooksByIdAndName(String name, Integer id);
}
BookService.java
@Service
public class BookService {
@Autowired
BookDao bookDao;
public void addBook(Book book) {
bookDao.save(book);
}
public Page getBookByPage(Pageable pageable) {
return bookDao.findAll(pageable);
}
public List getBooksByAuthorStartingWith(String author){
return bookDao.getBooksByAuthorStartingWith(author);
}
public List getBooksByPriceGreaterThan(Float price){
return bookDao.getBooksByPriceGreaterThan(price);
}
public Book getMaxIdBook(){
return bookDao.getMaxIdBook();
}
public List getBookByIdAndAuthor(String author, Integer id){
return bookDao.getBookByIdAndAuthor(author, id);
}
public List getBooksByIdAndName(String name, Integer id){
return bookDao.getBooksByIdAndName(name, id);
}
}
BookController.java
@RestController
public class BookController {
@Autowired
BookService bookService;
@GetMapping("/findAll")
public void findAll() {
PageRequest pageable = PageRequest.of(2, 3);
Page page = bookService.getBookByPage(pageable);
System.out.println("总页数:"+page.getTotalPages());
System.out.println("总记录数:"+page.getTotalElements());
System.out.println("查询结果:"+page.getContent());
System.out.println("当前页数:"+(page.getNumber()+1));
System.out.println("当前页记录数:"+page.getNumberOfElements());
System.out.println("每页记录数:"+page.getSize());
}
}
PageRequest.of(2,3);设置从第二页开始,每页可显示三条记录
3-jpa多数据源配置
首先:导包。
org.springframework.boot
spring-boot-starter-data-jpa
com.alibaba
druid-spring-boot-starter
1.1.10
然后:全局配置文件中配两个源。
spring.datasource.one.password=xiong
spring.datasource.one.username=root
spring.datasource.one.url=jdbc:mysql://124.222.48.147:3306/chapter05-1
spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.two.password=xiong
spring.datasource.two.username=root
spring.datasource.two.url=jdbc:mysql://124.222.48.147:3306/chapter05-1
spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57InnoDBDialect
spring.jpa.properties.database=mysql
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.show-sql= true
注意:这里的配置与配置单独的jpa有区别,因为有后文的配置中要从JpaProperties中的getPropertis方法中获取所有jpa的相关配置,因此这里的属性前缀都是spring.jpa.properties
再然后:创建实体类User.java和根据两个配置好的数据源创建两个不同的jpa配置,代码如下。
@Entity(name = "t_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String gender;
private Integer age;
//省略getter/setter
config/JpaConfigOne.java
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "org.sang.dao1",
entityManagerFactoryRef = "entityManagerFactoryBeanOne",
transactionManagerRef = "platformTransactionManagerOne")
public class JpaConfigOne {
@Resource(name = "dsOne")
DataSource dsOne;
@Autowired
JpaProperties jpaProperties;
@Bean
@Primary
LocalContainerEntityManagerFactoryBean entityManagerFactoryBeanOne(
EntityManagerFactoryBuilder builder) {
return builder.dataSource(dsOne)
.properties(jpaProperties.getProperties())
.packages("org.sang.model")
.persistenceUnit("pu1")
.build();
}
@Bean
PlatformTransactionManager platformTransactionManagerOne(
EntityManagerFactoryBuilder builder) {
LocalContainerEntityManagerFactoryBean factoryOne = entityManagerFactoryBeanOne(builder);
return new JpaTransactionManager(factoryOne.getObject());
}
}
config/JpaConfigTwo.java
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "org.sang.dao2",
entityManagerFactoryRef = "entityManagerFactoryBeanTwo",
transactionManagerRef = "platformTransactionManagerTwo")
public class JpaConfigTwo {
@Resource(name = "dsTwo")
DataSource dsTwo;
@Autowired
JpaProperties jpaProperties;
@Bean
LocalContainerEntityManagerFactoryBean entityManagerFactoryBeanTwo(
EntityManagerFactoryBuilder builder) {
return builder.dataSource(dsTwo)
.properties(jpaProperties.getProperties())
.packages("org.sang.model")
.persistenceUnit("pu2")
.build();
}
@Bean
PlatformTransactionManager platformTransactionManagerTwo(
EntityManagerFactoryBuilder builder) {
LocalContainerEntityManagerFactoryBean factoryTwo = entityManagerFactoryBeanTwo(builder);
return new JpaTransactionManager(factoryTwo.getObject());
}
}
*其后接下来:创建数据源分配文件DataSourceConfig.java
@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties("spring.datasource.one")
@Primary
DataSource dsOne() {
return DruidDataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties("spring.datasource.two")
DataSource dsTwo() {
return DruidDataSourceBuilder.create().build();
}
}
最后:创建dao和controller,测试
UserDao1.java
public interface UserDao1 extends JpaRepository{
}
UserDao2.java
public interface UserDao2 extends JpaRepository{
}
UserController.java
@RestController
public class UserController {
@Autowired
UserDao userDao;
@Autowired
UserDao2 userDao2;
@GetMapping("/test1")
public void test1() {
User u1 = new User();
u1.setAge(55);
u1.setName("鲁迅");
u1.setGender("男");
userDao.save(u1);
User u2 = new User();
u2.setAge(80);
u2.setName("泰戈尔");
u2.setGender("男");
userDao2.save(u2);
}
}
springboot整合NoSQL(整合Redis,MongoDB 与Session共享)
Redis简介
------Redis是一个使用C语言编写的基于内存的NoSql数据库,它是目前最流行的键值对存储数据库。Redis是由一个Key,Value映射的字典构成,与其它NoSQL不同,Redis中的Value的类型不局限于字符串,还支持冽 表,集合,有序集合,散列等。Redis不仅可以当作缓存使用,还可以配置持久化后当作Nosql数据库用.
Redis安装
安装环境为CENTOS 7
1.下载Redis
wget http://download.redis.io/releases/redis-4.0.10.tar.gz
//若是未找到命令,则
yum install wget
2.安装
tar -zxvf redis-4.0.10.tar.gz
cd redis-4.0.10
make MALLOC=libc
make install
//若未安装gcc,则安装
yum install gcc
3.配置Redis
----安装成功后,接下来进行配置,打开安装目录下的redis.conf文件主要修改以下几个地方,vi工具修改。
(ESC退出当前模式,/string查找相应的字符串,若想查找下一个按n , :wq!退出保存)
daemonizeyes
#bind 127.0.0.1
requirepass 123@456
protected-mode no
-----------------------------------------------------------------------------------------------------------------------------------------------
第1行配置表示允许Redis在后台运行
第2行配配置表示允许连接该Redis实例的地址,默认情况下只允许本地连接,将默认地址注释掉,外网就可以访问它了。
第3行配置表示登录该Redis的所需的密码
第4行配置,表示由于有第3行的密码登录,就可以不用保护了。
4.配置远程访问
-----为了能够远程连接Redis,还需要关闭防火增。
systemctl stop firewalld.service
systemctl disable firewalld.service
5.Redis启动与关闭
一,启动并进入控制台
redis-server redis.conf
redis-cli -a 123@456
二,关闭实例
redis-cli -p 6379 -a 123@456 shutdown
springboot整合Redis
1-导包
org.springframework.boot
spring-boot-starter-data-redis
io.lettuce
lettuce-core
redis.clients
jedis
注意:此处是排除了lettuce客户端包,用了流行的jedis客户端*
2-全局配置文件,下面为lettuce和jedis都做了配置
spring.redis.database=0
spring.redis.host=192.168.58.131
spring.redis.port=6379
spring.redis.password=123@456
spring.redis.lettuce.pool.max-active=100
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.max-wait=8
spring.redis.lettuce.pool.min-idle=8
spring.redis.lettuce.shutdown-timeout=8
spring.redis.jedis.pool.max-active= 8
spring.redis.jedis.pool.max-idle=8
spring.redis.jedis.pool.max-wait= -1ms
spring.redis.jedis.pool.min-idle= 0
3-创建实体类Book
public class Book implements Serializable {
private Integer id;
private String name;
private String author;
//省略getter/setter/toString
4-控制类
@RestController
public class BookController {
@Autowired
RedisTemplate redisTemplate;
@Autowired
StringRedisTemplate stringRedisTemplate;
@GetMapping("/test1")
public void test1() {
ValueOperations ops1 = stringRedisTemplate.opsForValue();
ops1.set("name", "三国演义");
String name = ops1.get("name");
System.out.println(name);
ValueOperations ops2 = redisTemplate.opsForValue();
Book b1 = new Book();
b1.setId(1);
b1.setName("红楼梦");
b1.setAuthor("曹雪芹");
ops2.set("b1", b1);
Book book = (Book) ops2.get("b1");
System.out.println(book);
}
}
-----------------------------------------------------------------------------------------------------------------------------------------------
三国演义
Book{id=1, name='红楼梦', author='曹雪芹'}
--------StringRedisTemplate是RedisTemplate的子类,StringRedisTemplate中的key,value都是字符串,采用序列化方案是StringRedisSerializer.而RedisTemplate则可用来操作对象。StringRedisTemplate和RedisTemplate都是通过opsForValue,opsForZSet或者opsForSet等方法首先获取一个操作对象,再使用访操作对象完成数据的读写
-
Redis集群整合spring boot
安装RVM工具
gpg2 --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3
https://blog.csdn.net/qq_42815754/article/details/82912130
https://blog.csdn.net/liulianglin/article/details/120444446