为什么会有springboot----->因为在spring、springmvc中需要写大量的配置文件,还需要配置各种对象,把使用的对象放入到spring容器中才能使用对象,还需要了解其他框架配置规则。
Spring家族推出springboot框架就是为了简化spring的配置与开发,使得在基于Spring框架的开发中开发起来更快速更方便,简化或减少相关的配置,提高开发效率;
SpringBoot 就相当于 不需要配置文件的Spring+SpringMVC------>常用的框架和第三方库都已经配置好了。 //开发效率高
JavaConfig:
spring框架提供的一个功能,使用java类作为xml配置文件的替代,是配置spring容器的纯java的方式。
在这个java类(配置文件类)这可以创建java对象,把对象放入spring容器中(注入到容器)
Spring使用Xml作为容器配置文件------------》在3.0以后加入了JavaConfig(java类配置容器)配置Spring IOC容器的纯Java方法。使用:创建普通类,定义方法,方法返回值是对象
@Configuration注解: 位置:类上 作用:表示这个类是作为配置文件使用的。 //相当于spring配置文件xml
属性:@Bean注解: 位置:方法上 作用:声明对象,把方法的返回值(对象)注入到容器中。 //相当于<bean>标签
属性:name 指定对象的名称(说明:若不指定对象的名称,默认方法名是id) //相当于<bean>标签的id属性注解的位置对应之前spring中配置文件中的标签
@ImportResource注解: 位置:类上 作用:导入已有的xml配置文件 //相当于xml文件的<import resources="其他配置文件"/>
属性:value String数组,指定配置文件的位置(一般为calsspath:xxx类路径下)@ComponentScan注解 位置:类上 作用:告诉配置文件类,去哪里找其他注解 //相当于组件扫描器标签<context:component-scan base-package="注解所在的包名"/>
属性:basePackages 读取注其他注解所在的包名
@PropertyResource注解: 位置:类上 作用:把让spring框架的配置文件类读到属性配置文件(properties)
属性:value String数组,指定.properties属性文件的位置(一般为calsspath:xxx类路径下)
//相当于<context:property-placeholder location="classpath:conf/jdbc.properties"/>使用:
- 在resources目录下创建xxx.properties文件,使用k=v格式提供数据
- 根据xxx.properties文件创建一个Java普通类用来获取数据,私有属性为k
- 在类上使用@Component("id")使用注解生成对象放入容器
- 在属性上使用@Value(value="${key}")
- 在JavaConfig的Java类上@PropertyResource(value="classpath:xxx属性文件") 把让spring框架的配置文件类读到属性文件
- 在JavaConfig的Java类上@ComponentScan(basePackages = "类所在包名") //组件扫描器找到注解生成对象
使用JavaConfig:在JavaConfig创建容器对象:ApplicationContext ctx = new AnnotationConfigApplicationContext(配置文件类.class);
获取对象:Student student = (Student) ctx.getBean("id名"); //注意要转换类型,因为都是Object
SpringBoot
SpringBoot是Spring中的一个成员,可以简化spring、springmvc的使用。核心还是IoC容器
特点:创建spring应用
内嵌的tomcat, jetty , Undertow 服务器
提供了starter起步依赖,简化应用的配置。 //比如使用MyBatis框架 , 需要在Spring项目中,配置MyBatis的对象 SqlSessionFactory , Dao的代理对象
//现在在SpringBoot项目中,在pom.xml里面, 加入一个 mybatis-spring-boot-starter依赖,上面的就配置好了
自动配置:尽可能去配置spring和第三方库。(就是把spring中的、第三方库中的对象都创建好,放到容器中, 开发人员可以直接使用)
提供了健康检查, 统计,外部化配置(属性配置文件就是外部化配置)
不用生成代码, 不用使用xml,做配置
创建springboot项目
第一种方式:使用Spring提供的初始化器, 就是向导创建SpringBoot应用 //使用地址:https://start.spring.io/ //需要联网
![]()
.mvn 与maven有关的 //可以删除
mvnw 与maven有关的 //可以删除
mvnw.cmd 与maven有关的 //可以删除
HELP.md 描述文件 //可以删除
.gitignore git忽略文件 //不用管
xxx.iml IDEA自己的文件 //不用管
重点:
pom.xml
src
pom.xml文件:<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> springboot项目的父项目 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.4</version> <relativePath/> <!-- lookup parent from repository --> </parent> 当前项目的坐标 <groupId>groupId</groupId> <artifactId>artifactId</artifactId> <version>0.0.1-SNAPSHOT</version> <name>artifactId</name> 可以删除不要 <description>artifactId</description> 可以删除不要 jdk版本 <properties> <java.version>1.8</java.version> </properties> 依赖 <dependencies> web依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> web项目的起步依赖,会加入相关需要的的jar包 </dependency> 测试依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> maven插件 <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>调试项目:
![]()
第二种方式:使用Spring提供的初始化器, 就是向导创建SpringBoot应用 //使用地址:https://start.springboot.io/(上面的地址是国外的,经常访问失败,所以用国内的)
第三种方式:使用浏览器进入上面的网址,在生成项目,下载压缩包,解压后导入idea---maven工程就可以
第四种方式:maven----不用选模板----创建普通的maven项目-----在pom.xml加入父项目和起步依赖
在resources文件夹种新建:2个文件夹:static、templates 1个文件application.properties
@SpringBootApplication public class Application { //主启动类 public static void main(String[] args) { //主方法 SpringApplication.run(Application.class,args); //启动spring IoC容器,返回容器 } }@SpringBootApplication注解: 位置:主类上
复合注解:由@SpringBootConfiguration (配置文件) 三个注解组成
@EnableAutoConfiguration (自动配置功能)
@ComponentScan (扫描注解)
@SpringBootConfiguration注解: //该注解的注解:@Configuration注解 //该类可以当作配置文件来用,可以使用Bean(标签、注解)声明对象,注入到容器
@Configuration public @interface SpringBootConfiguration { @AliasFor( annotation = Configuration.class ) boolean proxyBeanMethods() default true; }@EnableAutoConfiguration: 启用自动配置, 把java对象配置好,注入到spring容器中 //例如可以把mybatis的对象创建好,放入到容器中
@ComponentScan:组件扫描器,找到注解,根据注解的功能创建对象,给属性赋值等等。
默认扫描的包: @ComponentScan所在的类所在的包和子包。
Spring Boot配置文件:.properties格式文件(k=v)、.yml格式文件(k: v)
核心配置文件:名字必须以 application 开始 //如:application.properties、application.yml 若2个都配置则冲突,优先用.properties
application.properties格式文件:#设置端口号 server.port=8080 #应用的上下文路径contextpath 项目 server.servlet.context-path=/xxxapplication.yml格式文件: //有层级关系:一般习惯2个空格 k:与v有一个空格 //推荐使用
server: port: 8080 servlet: context-path: /xxx多环境配置:开发时,项目会经历多个阶段(开发->测试->上线),每个阶段环境配置不同(如:端口、上下文根、数据库等)
为了方便不同环境来回切换,SpringBoot 提供了多环境配置:为每个环境创建一个配置文件,命名规则: application-自定义环境标识.properties|yml
在application.properties|yml设置激活哪个配置文件 //以application.properties为例#指定使用的环境文件 spring.profiles.active=自定义环境标识 #自定义环境标识习惯一般用:dev开发、test测试、online上线Spring Boot 自定义配置:
@value("${key}")注解 位置:类的属性上 从属性配置文件(application.properties、application.yml)获取数据,赋值给属性
@ConfigurationProperties注解 将整个文件映射成一个对象
属性:prefix 值为字符串,为配置文件中key的.之前的字符串 //如: aaa.bbb=xxxx aaa为.之前的值 bbb为.之后的值 这样做是为了抽取想要的属性
使用 1)创建一个类,定义私有属性(名与配置文件的key名相同,注意:key名是.之后的字符串)
2)在类上使用@ConfigurationProperties注解进行映射
3)在类上使用@Component注解创建对象
类中使用了 ConfigurationProperties 注解, IDEA 会出现一个警告 ,不影响程序的执行。解决:可以加入依赖项
<!--解决使用@ConfigurationProperties注解出现警告问题-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
Spring Boot中使用JSP
// 不推荐使用jsp在spring boot,会用模板技术来替代jsp作为视图使用
- 加入一个处理jsp的依赖,负责编译jsp文件
<!--引入Spring Boot内嵌的Tomcat对JSP的解析包,不加解析不 了jsp页面--> <!--如果只是使用JSP页面,可以只添加该依赖--> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> </dependency>如果需要使用servlet, jsp,jstl的功能,加入其依赖
<dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.1</version> </dependency>创建存放jsp的目录:webapp 新建有index.jsp
在pom.xml指定jsp文件的编译后的存放目录 META-INF/resources
<resources> <resource> <!--jsp文件的源文件位置--> <directory>src/main/webapp</directory> <!--指定编译到META-INF/resource,该目录不能随便写--> <targetPath>META-INF/resources</targetPath> <!--指定要把哪些文件编译进去,**表示webapp目录及子目录,*.*表示所有文件--> <includes> <include>**/*.*</include> </includes> </resource> </resources>创建Controller,访问jsp //直接使用视图逻辑名称
在application.propertis文件中配置视图解析器
#配置SpringMVC的视图解析器 #其中:/相当于src/main/webapp目录 spring.mvc.view.prefix=/ spring.mvc.view.suffix=.jsp
Spring Boot中使用 ApplicationContext
在main方法中SpringApplication.run()方法获取返回的Spring容器对象
run方法:public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) { return run(new Class[]{primarySource}, args); } ConfigurableApplicationContext : 接口,是ApplicationContext的子接口 public interface ConfigurableApplicationContext extends ApplicationContext
在容器启动后执行后执行一些内容。比如读取配置文件,数据库连接之类的。SpringBoot 给我们提供了两个接口来帮助我们实现这种需求:在启动类上实现该接口
CommandLineRunner接口
方法:run //区别:方法的参数为 String数组 void run(String... args) 是main方法传入的参数
ApplicationRunner接口
方法:run //区别:方法的参数为 ApplicationArguments void run(ApplicationArguments args)
执行时间:容器对象创建好后,自动执行run方法
Spring Boot 和 web 组件
拦截器组件:
拦截器是SpringMVC中一种对象,能拦截器对Controller的请求。
拦截器框架中有系统的拦截器, 还可以自定义拦截器。 实现对请求预先处理。
- 创建类实现SpringMVC框架的HandlerInterceptor接口 //即springmvc中的做法
- 在SpringBoot中注册拦截器 //之前是在SpringMVC的配置文件中,声明拦截器。
@Configuration //代替xml配置文件 public class MyAppConfig implements WebMvcConfigurer { //创建类实现WebMvcConfigurer 接口,该接口有很多springmvc有关的功能 //添加拦截器对象, 注入到容器中 public void addInterceptors(InterceptorRegistry registry) { //形参相当于是个注册器 //创建拦截器对象 HandlerInterceptor interceptor = new LoginInterceptor(); //指定拦截的请求uri地址 String path []= {"/user/**"}; //指定不拦截的地址 String excludePath [] = {"/user/login"}; registry.addInterceptor(interceptor) //添加拦截器 .addPathPatterns(path) //拦截哪个请求地址 .excludePathPatterns(excludePath); //不拦截哪个请求地址 } }Servlet组件:
- 创建Servlet类。 创建类继承HttpServlet
- 在SpringBoot注册Servlet ,让框架能找到Servlet //在自定义类中实现返回值ServletRegistrationBean 的方法
@Configuration public class WebApplictionConfig { //定义方法, 注册Servlet对象 @Bean public ServletRegistrationBean servletRegistrationBean(){ 方式一有参构造:public ServletRegistrationBean(T servlet, String... urlMappings) 第一个参数是 Servlet对象, 第二个是url地址 ServletRegistrationBean bean = new ServletRegistrationBean( new HttpServlet继承类(),"/myservlet"); --------------------------------------------------------------------------------------------- 方式二无参构造:public ServletRegistrationBean() ServletRegistrationBean bean = new ServletRegistrationBean(); bean.setServlet( new HttpServlet继承类()); //无参构造创建的需要手动设置servlet对象 bean.addUrlMappings("/login","/test"); // 手动设置<url-pattern> return bean; } }
过滤器Filter组件
Filter是Servlet规范中的过滤器,可以处理请求, 对请求的参数, 属性进行调整。 常常在过滤器中处理字符编码
- 创建自定义过滤器类
- 在SpringBoot中注册Filter //在自定义类中实现返回值FilterRegistrationBean的方法
@Configuration public class WebApplicationConfig { @Bean public FilterRegistrationBean filterRegistrationBean(){ FilterRegistrationBean bean = new FilterRegistrationBean(); //同上,也分有参构造、无参构造 bean.setFilter( new 自定义过滤器类()); bean.addUrlPatterns("/user/*"); return bean; } }
字符集过滤器组件:
CharacterEncodingFilter : 解决post请求中乱码的问题
在SpringMVC框架, 在web.xml 注册过滤器。 配置他的属性。
使用方式一:
- 配置字符集过滤器
@Configuration public class WebSystemConfig { //注册Servlet @Bean public ServletRegistrationBean servletRegistrationBean(){ MyServlet myServlet = new MyServlet(); ServletRegistrationBean reg = new ServletRegistrationBean(myServlet,"/myservlet"); return reg; } //注册Filter @Bean public FilterRegistrationBean filterRegistrationBean(){ FilterRegistrationBean reg = new FilterRegistrationBean(); //使用框架中的过滤器类 CharacterEncodingFilter filter = new CharacterEncodingFilter(); //指定使用的编码方式 filter.setEncoding("utf-8"); //指定request , response都使用encoding的值 filter.setForceEncoding(true); reg.setFilter(filter); //指定 过滤的url地址 reg.addUrlPatterns("/*"); return reg; } }- 修改application.properties文件, 让自定义的过滤器起作用
#SpringBoot中默认已经配置了CharacterEncodingFilter。 编码默认ISO-8859-1 #设置enabled=false 作用是关闭系统中配置好的过滤器, 使用自定义的CharacterEncodingFilter server.servlet.encoding.enabled=false
使用方式二:使用已有的CharacterEncodingFilter过滤器 ------>修改application.properties文件
#让系统的CharacterEncdoingFilter生效 server.servlet.encoding.enabled=true #指定使用的编码方式 server.servlet.encoding.charset=utf-8 #强制request,response都使用charset属性的值 server.servlet.encoding.force=true
ORM操作MySQL
ORM:指mybatis框架,mybatis是ORM的一种
spring boot集成mybatis使用步骤:
- mybatis起步依赖 : 完成mybatis对象自动配置, 对象放在容器中
,就会加入mybatis的起步依赖、MySQL驱动
- pom.xml 指定把src/main/java目录中的xml文件包含到classpath中
<resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources>- 创建实体类Student
- 创建Dao接口 StudentDao , 创建一个查询学生的方法
- 创建Dao接口对应的Mapper文件, xml文件, 写sql语句
- 创建Service层对象, 创建StudentService接口和他的实现类。 去dao对象的方法。完成数据库的操作
- 创建Controller对象,访问Service
- 写application.properties文件配置数据库的连接信息
#连接数据库: #使用的是mysql驱动新版本的驱动类 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver #连接数据库的url信息 spring.datasource.url=jdbc:mysql://localhost:3306/springdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8 #用户信息 spring.datasource.username=root spring.datasource.password=123方式一:@Mapper注解 位置:放在dao接口的上面 //缺点:若有很多接口,则需要加的太多
作用:告诉MyBatis这是dao接口,创建此接口的代理对象。
方式二:@MapperScan注解 位置:主启动类上
属性:basePackages 字符串数组,指定接口所在的包名
作用:找到所有dao接口,创建此接口的代理对象。Mapper文件和Dao接口分开管理
把Mapper文件放在resources目录下:
- 在resources目录中创建子目录 (自定义的) , 例如mapper
- 把mapper文件放到 mapper目录中
- 在application.properties文件中,指定mapper文件的目录:
#指定mapper文件的位置 mybatis.mapper-locations=classpath:mapper/*.xml #指定mybatis的日志 mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl- 在pom.xml中指定 把resources目录中的文件 , 编译到目标目录中
<!--resources插件--> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.*</include> </includes> </resource> </resources>事务
Spring Boot 使用事务非常简单,底层依然采用的是Spring本身提供的事务管理
Spring框架中的事务:
- 管理事务的对象: 事务管理器(接口, 接口有很多的实现类)
- 声明式事务: 在xml配置文件或者使用注解说明事务控制的内容
控制事务: 隔离级别,传播行为, 超时时间- 事务处理方式:
- 方式一:Spring框架中的@Transactional
- 方式二:aspectj框架可以在xml配置文件中,声明事务控制的内容
SpringBoot中使用事务: 上面的两种方式都可以。
- 在业务方法(Service方法)的上面加入@Transactional, 加入注解后,方法就有事务功能了。 //默认使用库的隔离级别, REQUIRED 传播行为; 超时时间 -1
- 明确的在 主启动类的上面 ,加入@EnableTransactionManager,加入注解后,表示启用事务管理器 //可不使用该注解,最后加上
接口架构风格 —RESTful
接口:API(应用程序接口),指是一些预先定义的接口(如函数、HTTP接口-->url)。让开发人员使用,无需访问源码或理解内部工作机制的细节便可以完成对应的功能
可以指访问servlet, controller的url, 调用其他程序的函数架构风格: api组织方式(样子)
就是一个传统的:http://localhost:9002/mytrans/addStudent?name=lisi&age=26
在地址上提供了 访问的资源名称addStudent, 在其后使用了get方式传递参数。
RESTful架构风格 :
之前访问HTTP接口: http://localhost:8080/boot/order?id=1021&status=1
RESTFul风格则http地址为:http://localhost:8080/boot/order/1021/1 //在url种使用名词表示资源,以及资源的访问信息(使用/来分隔对资源的信息),而不是?参数REST(表现层状态转移: ):是一种客户端和服务器交互时的架构理念和设计原则、理念,不是标准。 //优点:简洁、有层次
表现层:就是视图层, 显示资源的, 通过视图页面,jsp等等显示操作资源的结果。
状态: 资源变化
转移: 资源可以变化的。 资源能创建,new状态, 资源创建后可以查询资源, 能看到资源的内容,这个资源内容 ,可以被修改, 修改后资源 和之前的不一样。
REST中的要素: 用REST表示资源和对资源的操作。 在互联网中,表示一个资源或者一个操作。
资源使用url表示的, 在互联网, 使用的图片,视频, 文本,网页等等都是资源。
资源是用名词表示。对资源: 查询资源: 看,通过url找到资源。
创建资源: 添加资源
更新资源:更新资源 ,编辑
删除资源: 去除资源使用url表示,通过名词表示资源。使用http中的动作(请求方式), 表示对资源的操作(CURD)
GET: 查询资源 -- sql select http://localhost:8080/myboot/student/1001 //在url种使用名词表示资源,以及资源的访问信息(使用/来分隔对资源的信息)
http://localhost:8080/myboot/students/1001/1002
POST: 创建资源 -- sql insert 1) http://localhost:8080/myboot/student 2) 然后在post请求中传递数据通常用get/post,后面2种方式浏览器默认不支持的,可以用get/post来模拟更新删除资源:
PUT: 更新资源 -- sql update //使用post方式模拟put<form action="http://localhost:8080/myboot/student/1" method="post"> 姓名:<input type="text" name="name" /> 年龄:<input type="text" name="age" /> <input type="hidden" name="_method" value="PUT" /> //让后端知道模拟的是PUT </form>DELETE: 删除资源 -- sql delete //使用get模拟delete
<a href="http://localhost:8080/myboot/student/1">删除1的数据</a>注意:需要的分页, 排序等参数,依然放在 url的后面, 例如 http://localhost:8080/myboot/students?page=1&pageSize=20
(与资源紧密相关的放在url,其他不是很重要的依然用参数)对REST风格支持的注解:
@PathVariable : 从url中获取数据 位置: 在逐个接收参数中,在形参定义的前面
属性:value 路径变量名
例如: @GetMapping("/stydent/{变量名}/{变量名}") ----> http://localhost:8080/myboot/student/1001/1002 {变量名}:表示定义路径变量
控制器方法(@PathVariable(value = "变量名") Integer id, @PathVariable String 变量名) //value可简写 //路径变量名和形参名相同时,该属性可省略@GetMapping: 支持的get请求方式, 等同于 @RequestMapping( method=RequestMethod.GET) 位置:控制器方法上
属性:value 路径 //可以使用路径变量{变量名}表示一个位置 //请求方式+地址:格式必须保证唯一,否则出现多个格式相同的,就不知道访问具体哪个了@PostMapping: 支持post请求方式 ,等同于 @RequestMapping( method=RequestMethod.POST) 同上
@PutMapping: 支持put请求方式, 等同于 @RequestMapping( method=RequestMethod.PUT) 同上
@DeleteMapping: 支持delete请求方式, 等同于 @RequestMapping( method=RequestMethod.DELETE) 同上
@RestController: 复合注解, 是@Controller 和@ResponseBody组合。
在类的上面使用@RestController , 表示当前类者的所有方法都加入了 @ResponseBody
//使用Postman去测试工具测试请求 //还可以使用idea插件:tool下最后一个选项,与Postman功能相同
在页面中或者ajax中,支持put,delete请求
在SpringMVC中 有一个过滤器, 支持post请求转为put ,delete
过滤器: org.springframework.web.filter.HiddenHttpMethodFilter //作用: 把请求中的post请求转为 put , delete实现步骤:在springmvc框架中,需要在web.xml文件中配置去启用(方式直接上网上找),在spring boot框架中该过滤器已启用,直接用就可以:
application.properties(yml) : 开启使用 HiddenHttpMethodFilter 过滤器
#启用 HiddenHttpMethodFilter 这个过滤器, 支持post请求转为 put,delete spring.mvc.hiddenmethod.filter.enabled=true在请求页面中,包含 _method参数, 他的值是 put, delete , 发起这个请求使用的post方式
<form action="http://localhost:8080/myboot/student/1" method="post"> 姓名:<input type="text" name="name" /> 年龄:<input type="text" name="age" /> <input type="hidden" name="_method" value="PUT" /> </form>
springboot继承redis
redis是一个中间件:是一个独立的服务器
java中著名的客户端:Jedis、lettuce、Redisson
Spring,SpringBoot中有 一个RedisTemplate类(StringRedisTemplate类) ,处理和redis的交互
windows环境redis的客户端和服务端:只做开发使用
redisclient-win32.x86_64.2.0.jar : Redis图形界面客户端 //执行方式: 在这个文件所在的目录, 执行 java -jar redisclient-win32.x86_64.2.0.jar
添加依赖:
里面有:
<!--redis起步依赖: 直接在项目中使用RedisTemplate(StringRedisTemplate)--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> data-redis使用的 lettuce 客户端库 在程序中使用RedisTemplate类的方法 操作redis数据, 实际就是调用的lettuce 客户端的中的方法在配置文件application.properties指定redis配置信息:
#指定redis spring.redis.host=localhost //IP spring.redis.port=6379 //端口号 #spring.redis.password=123456 //有密码就设置上创建controller层:
@RestController public class RedisController { /*注入RedisTemplate 泛型key,value都是String ,或者Object, 不写 RedisTemplate<String,String> RedisTemplate<Object,Object> RedisTemplate 注意:RedisTemplate对象的名称要写成redisTemplate */ @Resource private RedisTemplate redisTemplate; //有对象是因为加了起步依赖,有框架创建对象,然后注入到这里 默认使用JDK序列化 @StringResource private StringRedisTemplate stringredisTemplate; //道理如上 默认使用String序列化 @GetMapping("/myname") public String getName(){ //操作redis什么类型数据就要先获取操作对象 //获取RedisTemplate或StringRedisTemplate操作对象 redisTemplate.opsFor数据类型(); //通过操作对象的方法来操作数据 操作对象.set("xx","xxx") .xxx(参数) //方法名与redis命令名相同 -------------------------------------------------------------- //设置RedisTemplate或StringRedisTemplate操作对象的序列化 操作对象获取值的适合就会自动反序列化回来,所需取出值直接用就可 //可以设置key的序列化,也可以设置value的序列化,还可以同时设置 设置RedisTemplate对象的key序列化 //例子设为String方式 redisTemplate.setKeySerializer( new StringRedisSerializer()); //查看方法的参数类型,查看参数的实现类---就是序列化方式,new对象作为参数 设置RedisTemplate对象的value序列化 redisTemplate.setValueSerializer( new StringRedisSerializer()); 然后再获取操作对象,进行操作就可以了,注意被序列化的对象要设置JDK序列化版本号不变,不然反序列化回不来哦 -------------------------------------------------------------- return 向redis添加数据; } }区别:
StringRedisTemplate : 把k,v 都是作为String处理, 使用的是String的序列化 , 可读性好RedisTemplate : 把k,v 经过了序列化存到redis。 k,v 是序列化的内容, 不能直接识别. // 默认使用的jdk序列化, 可以修改为前提的序列化
序列化:把对象转化为可传输的字节序列过程称为序列化。
反序列化:把字节序列还原为对象的过程称为反序列化。
为什么需要序列化:序列化最终的目的是为了对象可以跨平台存储,和进行网络传输。而我们进行跨平台存储和网络传输的方式就是IO,而我们的IO支持的数据格式就是字节数组。我们必须在把对象转成字节数组的时候就制定一种规则(序列化),那么我们从IO流里面读出数据的时候再以这种规则把对象还原回来(反序列化)。
序列化的方式:序列化只是一种拆装组装对象的规则,那么这种规则肯定也可能有多种多样,比如现在常见的序列化方式有:
JDK(不支持跨语言)、JSON、XML、Hessian、Kryo(不支持跨语言)、Thrift、Protofbuff、
springboot集成Dubbo
阿里巴巴提供了dubbo集成springBoot开源项目,
可以到GitHub上https://github.com/apache/dubbo-spring-boot-project 查看入门教程
- 按照Dubbo官方开发建议,创建一个接口项目(普通maven项目),该项目只定义接口和model类。
- 创建服务提供者项目(springboot项目)
- 额外在springboot引入Dubbo、zookeeper等依赖项:dubbo-spring-boot-starter、dubbo-dependencies-zookeeper、添加接口项目依赖、<!-- 排除log4j依赖 -->
- 实现接口
- 在接口实现类上使用注解暴露出去
@DubboService(interfaceClass = 接口.class,version = "版本号",timeout="超时时间")
该注解的interfaceClass属性默认就是实现接口类型 //所以可以不用写- 在接口实现类上使用注解把对象注入容器 //可以不用加该注解,加上了也没影响
@Component- 在配置文件application.properties
#配置服务名称 相当于<dubbo:application>的name属性 spring.application.name=xxxx #配置dubbo注解所在的包名 ---->@DubboService dubbo.scan.base-packages=包名 #配置dubbo协议 #dubbo.protocol.name=dubbo #dubbo.protocol.prot=端口号 #配置zookeeper注册中心 dubbo.registry.address=zookeeper://localhost:2181- 在启动类上加上注解:@EnableDubbo //启用dubbo
- 创建消费者项目(springboot项目)
- 添加相同的依赖
- 编写controller层或者 Service层都可以 ///以controller层为例
- 在controller层的类上添加接口类型私有属性,在私有属性上添加注解把对象传过来:
@DubboReference(interfaceClass = 接口类型.class,version = "版本",check = false) //引用远程服务,把创建好的代理对象注入给该属性
该注解的interfaceClass属性默认就是该属性的类型 //所以可以不用写- 在配置文件application.properties
#配置服务名称 相当于<dubbo:application>的name属性 spring.application.name=xxxx #指定注册中心 dubbo.registry.address=zookeeper://localhost:2181- 在启动类上加上注解:@EnableDubbo //启用dubbo
- 启动zookeeper、启用提供者、消费者
打包
Spring Boot 可以打包为 war 或 jar文件。 以两种方式发布应用
使用maven打包:打包成war ---> maven package target目录有war文件:xxx.war tomcat为例, myboot.war放到tomcat/webapps目录----启动Tomcat---浏览器访问web应用
在pom.xml文件<build> <!--打包后的文件名称--> <finalName>xxx</finalName> </build> <!--打包类型--> <packaging>war</packaging>主启动类继承SpringBootServletInitializer::继承这个类, 才能使用独立tomcat服务器 //SpringBootServletInitializer就是原有的web.xml文件的替代
@SpringBootApplication public class JspApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(JspApplication.class, args); } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { return builder.sources(JspApplication.class); } }
打包成jar 同上
必须maven插件版本
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!--带有jsp的程序,打包为jar,必须指定spring-boot-maven-plugin版本是1.4.2.RELEASE-->
<version>1.4.2.RELEASE</version>
</plugin>maven package-------target目录有jar文件:mybootjar.jar---------java –jar xxxx.jar执行jar,启动内置的tomcat-----浏览器访问web应用
打包成jar和war的区别:war需要运行在服务器上,jar可以独立运行,内嵌Tocamt
Thymeleaf 模板引擎
Spring Boot 集成Thymeleaf模板技术, 使用Thymeleaf代替jsp。 Thymeleaf
Thymeleaf: 是使用java开发的模板技术, 在服务器端运行。 把处理后的数据发送给浏览器。
模板是作视图层工作的。 显示数据的。 Thymeleaf是基于Html语言。 Thymleaf语法是应用在html标签中 。
添加依赖:
模板引擎可以从request作用域中获取数据
模板视图文件就是html文件application.properties设置
#开发阶段设置为false ,上线后设置为 true spring.thymeleaf.cache=false # 设置模版文件的路径,前缀 spring.thymeleaf.prefix=classpath:/templates/ # 设置后缀 spring.thymeleaf.suffix=.html # 设置模版的类型 spring.thymeleaf.mode=HTML #设置模板的格式 spring.thymeleaf.encoding=utf-8模板文件:
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>第一个例子</title> </head> <body> <p th:text="${key}">向显示的数据</p> 使用使用request作用域的数据替换标签的文本内容 ------------------------------------------------------------------------------ <div th:object="${对象}"> //使用使用request的对象 <p th:text="*{属性}"></p> //使用对象的属性 <p th:text="*{name}"></p> //注意该Thymeleaf属性不能超过其对象的作用范围 <p th:text="*{sex}"></p> <p th:text="*{age}"></p> </div> <p th:text="*{对象.属性}" ></p> <p th:text="*{myuser.name}" ></p> ------------------------------------------------------------------------------ <a th:href="@{www.baidu.com}">xxxx</a> <script th:src="@{xxx}"> <a th:href="@{'/query/student?id='+${stuId}}">相对地址传参数方式1</a> <a th:href="@{/find/school(id=${stuId},name='lisi')}">相对地址传参数方式2</a> //推荐 ------------------------------------------------------------------------------ </body>标准变量表达式:${key} // 获取key对应的文本数据, key 是request作用域中的key ,若key是对象,则继续调用属性或方法, 使用request.setAttribute(), model.addAttribute()
在HTML标签中使用:th:text="${key}" //注意:th:text="" 是Thymeleaf的一个属性,用于文本的显示选择变量表达式:方式一: *{key} //获取key对应的数据
需要和th:object="${key}" 属性搭配使用(key为request作用域的对象,该属性要在*{}表达式的父元素)
在HTML标签中使用:th:text="*{属性名}"
方式二:在HTML标签中使用:th:text="*{对象.属性名}"连接表达式: @{url}
Thymeleaf属性:html原来的属性加上th:前缀。加了前缀的属性作用不变,就是属性值是经过模版引擎处理的,可以使用变量表达式。
th:action
th:method
th:href
th:src
th:text
th:value
th:style
th:each 循环:既可以循环遍历集合,也可以循环遍历数组及Map.集合循环成员,循环的状态变量:两个名称都是自定义的。 <div th:each="集合循环成员,循环的状态变量:${key}"> //循环list、array <p th:text="${集合循环成员}" ></p> </div> 参数二是循环体的信息:通过该变量可以获取以下信息 index: 当前迭代对象的index(从0开始计算) count: 当前迭代对象的个数(从1开始计算)这两个用的较多 size: 被迭代对象的大小 current: 当前迭代变量 even/odd: 布尔值,当前循环是否是偶数/奇数(从0开始计算) first: 布尔值,当前循环是否是第一个 last: 布尔值,当前循环是否是最后一个 注意:循环体信息interStat也可以不定义,则默认采用迭代变量加上Stat后缀,即:参一Stat 循环map比较特殊:参一是对象--》分为key、value <div th:each="m,mSt:${users}"> //循环map <p th:text="${mSt.count}"></p> <p th:text="${m.key}"> </p> <p th:text="${m.value.id}"></p> <p th:text="${m.value.name}"></p> </div>th:if 判断语句, 当条件为true, 显示html标签体内, 反之不显示 没有else语句 <div th:if=" 10 > 0 "> 显示文本内容 </div>
th:unless th:if相反的行为 <div th:unless=" 10 < 0 "> 当条件为false显示标签体内容 </div>
th:switch 和 java中的swith一样的<div th:switch="要比对的值"> <p th:case="值1"> 结果1 </p> <p th:case="值2"> 结果2 </p> <p th:case="*"> 默认结果 //*表示默认的case,前面的case都不匹配时候,执行默认的case </p> 以上的case只有一个语句执行 </div>th:inline 有三个取值类型 :text、 javascript 、none
- 内联text: 在html标签外,获取表达式的值 <p>显示姓名是:[[${key}]]</p>
<div th:inline="text"> <p>我是[[${name}]],年龄是[[${age}]]</p> </div> <p>我是[[${name}]],性别是[[${sex}]]</p> //inline="text"可写可不写- 内联javascript
<script type="text/javascript" th:inline="javascript"> var name = [[${myuser.name}]]; var id = [[${myuser.id}]]; function fun() { alert("click 用户是"+name+",他的id是"+id); } </script>字面量
<div style="margin-left: 400px"> <h3>文本字面量: 使用单引号括起来的字符串</h3> <p th:text="'我是'+${name}+',我所在的城市'+${city}">数据显示</p> <h3>数字字面量</h3> <p th:if="${20>5}"> 20大于 5</p> <h3>boolean字面量</h3> <p th:if="${isLogin == true}">用户已经登录系统</p> <h3>null字面量</h3> <p th:if="${myuser != null}">有myuser数据</p> </div>字符串连接: 单引号括起来字符串 , 使用 + 连接其他的字符串或者表达式 <p th:text="'我是'+${name}+',我所在的城市'+${city}">数据显示</p>
使用双竖线, |字符串和表达式| <p th:text="|我是${name},我所在城市${city}|">显示数据</p>算数运算符: + , - - , * , / , %
关系比较 : > , < , >= , <= ( gt , lt , ge , le )
相等判断: == , != ( eq , ne )
三元运算符: 表达式 ? true的结果 : false的结果内置对象
文档地址:Tutorial: Using Thymeleaf. 查看附录18
#request表示HttpServletRequest
#session表示HttpSession对象
session 表示Map对象的, 是#session的简单表示方式, 用来获取session中指定的key的值 -----》 #session.getAttribute("loginname") == session.loginname
这些是内置对象,可以在模板文件中直接使用:<div style="margin-left: 350px"> <h3>内置对象#request,#session,session的使用</h3> <p>获取作用域中的数据</p> <p th:text="${#request.getAttribute('requestData')}"></p> <p th:text="${#session.getAttribute('sessionData')}"></p> <p th:text="${session.loginname}"></p> <br/> <br/> <h3>使用内置对象的方法</h3> getRequestURL=<span th:text="${#request.getRequestURL()}"></span><br/> getRequestURI=<span th:text="${#request.getRequestURI()}"></span><br/> getQueryString=<span th:text="${#request.getQueryString()}"></span><br/> getContextPath=<span th:text="${#request.getContextPath()}"></span><br/> getServerName=<span th:text="${#request.getServerName()}"></span><br/> getServerPort=<span th:text="${#request.getServerPort()}"></span><br/> </div>Tymeleaf内置工具类对象 (文档附录19)
内置工具类型: Thymeleaf自己的一些类,提供对string, date ,集合的一些处理方法
#dates: 处理日器的工具类
#numbers:处理数字的
#lists: 处理list集合的
<div style="margin-left: 350px"> <h3>日期类对象 #dates</h3> <p th:text="${#dates.format(mydate )}"></p> <p th:text="${#dates.format(mydate,'yyyy-MM-dd')}"></p> <p th:text="${#dates.format(mydate,'yyyy-MM-dd HH:mm:ss')}"></p> <p th:text="${#dates.year(mydate)}"></p> <p th:text="${#dates.month(mydate)}"></p> <p th:text="${#dates.monthName(mydate)}"></p> <p th:text="${#dates.createNow()}"></p> <br/> <h3>内置工具类#numbers,操作数字的</h3> <p th:text="${#numbers.formatCurrency(mynum)}"></p> <p th:text="${#numbers.formatDecimal(mynum,5,2)}"></p> <br/> <h3>内置工具类#strings,操作字符串</h3> <p th:text="${#strings.toUpperCase(mystr)}"></p> <p th:text="${#strings.indexOf(mystr,'power')}"></p> <p th:text="${#strings.substring(mystr,2,5)}"></p> <p th:text="${#strings.substring(mystr,2)}"></p> <p th:text="${#strings.concat(mystr,'---java开发的黄埔军校---')}"></p> <p th:text="${#strings.length(mystr)}"></p> <p th:text="${#strings.length('hello')}"></p> <p th:unless="${#strings.isEmpty(mystr)}"> mystring 不是 空字符串 </p> <br/> <h3>内置工具类#lists,操作list集合</h3> <p th:text="${#lists.size(mylist)}"></p> <p th:if="${#lists.contains(mylist,'a')}">有成员a</p> <p th:if="!${#lists.isEmpty(mylist)}"> list 集合有多个成员</p> <br/> <h3>处理null,加上?当为null是后面的值不取,不然的话取null的属性会报错</h3> <p th:text="${zoo?.dog?.name}"></p> </div>自定义模板
模板是内容复用, 定义一次,在其他的模板文件中多次使用。
定义模板: th:fragment="模板自定义名称"
<div th:fragment="head"> <p> java开发 </p> <p> www.baidu.com </p> </div>引用模板: //若在不同目录下,文件名称使用---->路径文件名称 如:xxx/xx/文件名称
1) ~{templatename :: selector} templatename: 文件名称 selector: 自定义模板名称 2)templatename :: selector templatename: 文件名称 selector: 自定义模板名称 对于使用模板:有包含模板(th:include), 插入模板(th:insert)、 包含(替换使用标签) <div th:include="~{head :: top}"></div> <div th:include="head :: top"></div> 插入(插入使用标签内) <div th:insert="~{head :: top}"></div> <div th:insert="head :: top"></div>引用整个文件 <div th:include="~{文件名:: html}"></div> 或 <div th:include="~{文件名}"></div>
第十章 总结注解
Spring + SpringMVC + SpringBoot
创建对象的:
@Controller: 放在类的上面,创建控制器对象,注入到容器中
@RestController: 放在类的上面,创建控制器对象,注入到容器中。
作用:复合注解是@Controller , @ResponseBody, 使用这个注解类的,里面的控制器方法的返回值 都是数据@Service : 放在业务层的实现类上面,创建service对象,注入到容器
@Repository : 放在dao层的实现类上面,创建dao对象,放入到容器。 没有使用这个注解,是因为现在使用MyBatis框 架, dao对象是MyBatis通过代理生成的。 不需要使用@Repository、 所以没有使用。
@Component: 放在类的上面,创建此类的对象,放入到容器中。赋值的:
@Value : 简单类型的赋值, 例如 在属性的上面使用@Value("李四") private String name
还可以使用@Value,获取配置文件者的数据(properties或yml)。
@Value("${server.port}") private Integer port@Autowired: 引用类型赋值自动注入的,支持byName, byType. 默认是byType 。 放在属性的上面,也可以放在构造 方法的上面。 推荐是放在构造方法的上面
@Qualifer: 给引用类型赋值,使用byName方式。
@Autowird, @Qualifer都是Spring框架提供的。@Resource : 来自jdk中的定义, javax.annotation。 实现引用类型的自动注入, 支持byName, byType.
默认是byName, 如果byName失败, 再使用byType注入。 在属性上面使用
其他:
@Configuration : 放在类的上面,表示这是个配置类,相当于xml配置文件@Bean:放在方法的上面, 把方法的返回值对象,注入到spring容器中。
@ImportResource : 加载其他的xml配置文件, 把文件中的对象注入到spring容器中
@PropertySource : 读取其他的properties属性配置文件
@ComponentScan: 扫描器 ,指定包名,扫描注解的
@ResponseBody: 放在方法的上面,表示方法的返回值是数据, 不是视图
@RequestBody : 把请求体中的数据,读取出来, 转为java对象使用。@ControllerAdvice: 控制器增强, 放在类的上面, 表示此类提供了方法,可以对controller增强功能。
@ExceptionHandler : 处理异常的,放在方法的上面
@Transcational : 处理事务的, 放在service实现类的public方法上面, 表示此方法有事务
SpringBoot中使用的注解
@SpringBootApplication : 放在启动类上面, 包含了@SpringBootConfiguration
@EnableAutoConfiguration, @ComponentScan
MyBatis相关的注解@Mapper : 放在类的上面 , 让MyBatis找到接口, 创建他的代理对象
@MapperScan :放在主类的上面 , 指定扫描的包, 把这个包中的所有接口都创建代理对象。 对象注入到容器中
@Param : 放在dao接口的方法的形参前面, 作为命名参数使用的。
Dubbo注解
@DubboService: 在提供者端使用的,暴露服务的, 放在接口的实现类上面
@DubboReference: 在消费者端使用的, 引用远程服务, 放在属性上面使用。
@EnableDubbo : 放在主类上面, 表示当前引用启用Dubbo功能。







,就会加入mybatis的起步依赖、MySQL驱动
里面有:
