能源节点王鹤老师的SpringBoot入门系列课程,通俗易懂,基于SpringBoot2.4版本解说。
从细节动手,每个事例先解说pom.xml中的重要依赖,其次application配置文件,最初是代码实现。让你知其所以,逐渐让把握SpringBoot框架的主动配置,starter起步依赖等个性。
视频资源
https://www.bilibili.com/video/BV1XQ4y1m7ex
SpringBoot
第一章 JavaConfig
为什么要应用 Spring Boot
因为Spring, SpringMVC 须要应用的大量的配置文件 (xml文件)
还须要配置各种对象,把应用的对象放入到spring容器中能力应用对象
须要理解其余框架配置规定。
SpringBoot 就相当于 不须要配置文件的Spring+SpringMVC。 罕用的框架和第三方库都曾经配置好了。
拿来就能够应用了。
- SpringBoot开发效率高,使用方便多了
1.1 JavaConfig
JavaConfig: 应用java类作为xml配置文件的代替, 是配置spring容器的纯java的形式。 在这个java类这能够创立java对象,把对象放入spring容器中(注入到容器),
应用两个注解:
1)@Configuration : 放在一个类的下面,示意这个类是作为配置文件应用的。
2)@Bean:申明对象,把对象注入到容器中。
例子:package com.bjpowernode.config;import com.bjpowernode.vo.Student;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * Configuration:示意以后类是作为配置文件应用的。 就是用来配置容器的 * 地位:在类的下面 * * SpringConfig这个类就相当于beans.xml */@Configurationpublic class SpringConfig { /** * 创立办法,办法的返回值是对象。 在办法的下面退出@Bean * 办法的返回值对象就注入到容器中。 * * @Bean: 把对象注入到spring容器中。 作用相当于<bean> * * 地位:办法的下面 * * 阐明:@Bean,不指定对象的名称,默认是办法名是 id * */ @Bean public Student createStudent(){ Student s1 = new Student(); s1.setName("张三"); s1.setAge(26); s1.setSex("男"); return s1; } /*** * 指定对象在容器中的名称(指定<bean>的id属性) * @Bean的name属性,指定对象的名称(id) */ @Bean(name = "lisiStudent") public Student makeStudent(){ Student s2 = new Student(); s2.setName("李四"); s2.setAge(22); s2.setSex("男"); return s2; }}
1.2 @ImporResource
@ImportResource 作用导入其余的xml配置文件, 等于 在xml
<import resources="其余配置文件"/>
例如:
@Configuration@ImportResource(value ={ "classpath:applicationContext.xml","classpath:beans.xml"})public class SpringConfig {}
1.3 @PropertyResource
@PropertyResource: 读取properties属性配置文件。 应用属性配置文件能够实现内部化配置 ,
在程序代码之外提供数据。
步骤:
- 在resources目录下,创立properties文件, 应用k=v的格局提供数据
- 在PropertyResource 指定properties文件的地位
- 应用@Value(value="${key}")
@Configuration@ImportResource(value ={ "classpath:applicationContext.xml","classpath:beans.xml"})@PropertySource(value = "classpath:config.properties")@ComponentScan(basePackages = "com.bjpowernode.vo")public class SpringConfig {}
第二 章 Spring Boot
2.1 介绍
SpringBoot是Spring中的一个成员, 能够简化Spring,SpringMVC的应用。 他的外围还是IOC容器。
特点:
Create stand-alone Spring applications
创立spring利用
Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)
内嵌的tomcat, jetty , Undertow
Provide opinionated 'starter' dependencies to simplify your build configuration
提供了starter起步依赖,简化利用的配置。
比方应用MyBatis框架 , 须要在Spring我的项目中,配置MyBatis的对象 SqlSessionFactory , Dao的代理对象
在SpringBoot我的项目中,在pom.xml外面, 退出一个 mybatis-spring-boot-starter依赖
Automatically configure Spring and 3rd party libraries whenever possible
尽可能去配置spring和第三方库。叫做主动配置(就是把spring中的,第三方库中的对象都创立好,放到容器中, 开发人员能够间接应用)
Provide production-ready features such as metrics, health checks, and externalized configuration
提供了健康检查, 统计,内部化配置
Absolutely no code generation and no requirement for XML configuration
不必生成代码, 不必应用xml,做配置
2.2 创立Spring Boot我的项目
2.2.1 第一种形式, 应用Spring提供的初始化器, 就是向导创立SpringBoot利用
应用的地址: https://start.spring.io
SpringBoot我的项目的构造:
[外链图片转存失败,源站可能有防盗链机制,倡议将图片保留下来间接上传(img-dRfOaTEk-1645599534519)(D:\course\25-SpringBoot\笔记\images\image-20210115152427829.png)]
2.2.1 应用国内的地址
https://start.springboot.io
[外链图片转存失败,源站可能有防盗链机制,倡议将图片保留下来间接上传(img-IN52drB7-1645599534520)(D:\course\25-SpringBoot\笔记\images\image-20210115155556662.png)]
2.3 注解的应用
@SpringBootApplication合乎注解:由@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan 1.@SpringBootConfiguration @Configurationpublic @interface SpringBootConfiguration { @AliasFor( annotation = Configuration.class ) boolean proxyBeanMethods() default true;}阐明:应用了@SpringBootConfiguration注解标注的类,能够作为配置文件应用的, 能够应用Bean申明对象,注入到容器
2.@EnableAutoConfiguration
启用主动配置, 把java对象配置好,注入到spring容器中。例如能够把mybatis的对象创立好,放入到容器中
3.@ComponentScan
@ComponentScan 扫描器,找到注解,依据注解的性能创建对象,给属性赋值等等。默认扫描的包: @ComponentScan所在的类所在的包和子包。
2.4 SpringBoot的配置文件
配置文件名称: application
扩展名有: properties( k=v) ; yml ( k: v)
应用application.properties, application.yml
例1:application.properties设置 端口和上下文
#设置端口号server.port=8082#设置拜访利用上下文门路, contextpathserver.servlet.context-path=/myboot
例2: application.yml
server: port: 8083 servlet: context-path: /myboot2
2.5 多环境配置
有开发环境, 测试环境, 上线的环境。
每个环境有不同的配置信息, 例如端口, 高低文件, 数据库url,用户名,明码等等
应用多环境配置文件,能够不便的切换不同的配置。
应用形式: 创立多个配置文件, 名称规定: application-环境名称.properties(yml)
创立开发环境的配置文件: application-dev.properties( application-dev.yml )
创立测试者应用的配置: application-test.properties
2.6 @ConfigurationProperties
@ConfigurationProperties: 把配置文件的数据映射为java对象。
属性:prefix 配置文件中的某些key的结尾的内容。
@Component@ConfigurationProperties(prefix = "school")public class SchoolInfo { private String name; private String website; private String address; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getWebsite() { return website; } public void setWebsite(String website) { this.website = website; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "SchoolInfo{" + "name='" + name + '\'' + ", website='" + website + '\'' + ", address='" + address + '\'' + '}'; }}
application.properties
#配置端口号server.port=8082#context-pathserver.servlet.context-path=/myboot#自定义key=valueschool.name=能源节点school.website=www.bjpowernode.comschool.address=北京的大兴区site=www.bjpowernode.com
2.7 应用jsp
SpringBoot不举荐应用jsp ,而是应用模板技术代替jsp
应用jsp须要配置:
1) 退出一个解决jsp的依赖。 负责编译jsp文件
<dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId></dependency>
2) 如果须要应用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>
3) 创立一个寄存jsp的目录,个别叫做webapp
index.jsp
4) 须要在pom.xml指定jsp文件编译后的寄存目录。
META-INF/resources
5)创立Controller, 拜访jsp
6)在application.propertis文件中配置视图解析器
2.8 应用容器
你想通过代码,从容器中获取对象。
通过SpringApplication.run(Application.class, args); 返回值获取容器。
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) { return run(new Class[]{primarySource}, args);}ConfigurableApplicationContext : 接口,是ApplicationContext的子接口public interface ConfigurableApplicationContext extends ApplicationContext
2.9 ComnandLineRunner 接口 , ApplcationRunner接口
这两个接口都 有一个run办法。 执行工夫在容器对象创立好后, 主动执行run()办法。
能够实现自定义的在容器对象创立好的一些操作。
@FunctionalInterfacepublic interface CommandLineRunner { void run(String... args) throws Exception;}@FunctionalInterfacepublic interface ApplicationRunner { void run(ApplicationArguments args) throws Exception;}
第三章 Web组件
讲三个内容: 拦截器, Servlet ,Filter
3.1 拦截器
拦截器是SpringMVC中一种对象,能拦截器对Controller的申请。
拦截器框架中有零碎的拦截器, 还能够自定义拦截器。 实现对申请事后解决。
实现自定义拦截器:
创立类实现SpringMVC框架的HandlerInterceptor接口
public interface HandlerInterceptor { default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { }}
2.需在SpringMVC的配置文件中,申明拦截器
<mvc:interceptors> <mvc:interceptor> <mvc:path="url" /> <bean class="拦截器类全限定名称"/> </mvc:interceptor></mvc:interceptors>
SpringBoot中注册拦截器:
@Configurationpublic class MyAppConfig implements WebMvcConfigurer { //增加拦截器对象, 注入到容器中 @Override public void addInterceptors(InterceptorRegistry registry) { //创立拦截器对象 HandlerInterceptor interceptor = new LoginInterceptor(); //指定拦挡的申请uri地址 String path []= {"/user/**"}; //指定不拦挡的地址 String excludePath [] = {"/user/login"}; registry.addInterceptor(interceptor) .addPathPatterns(path) .excludePathPatterns(excludePath); }}
3.2 Servlet
在SpringBoot框架中应用Servlet对象。
应用步骤:
- 创立Servlet类。 创立类继承HttpServlet
- 注册Servlet ,让框架能找到Servlet
例子:
1.创立自定义Servlet
//创立Servlet类public class MyServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //应用HttpServletResponse输入数据,应答后果 resp.setContentType("text/html;charset=utf-8"); PrintWriter out = resp.getWriter(); out.println("===执行的是Servlet=="); out.flush(); out.close(); }}
- 注册Servlet
@Configurationpublic class WebApplictionConfig { //定义方法, 注册Servlet对象 @Bean public ServletRegistrationBean servletRegistrationBean(){ //public ServletRegistrationBean(T servlet, String... urlMappings) //第一个参数是 Servlet对象, 第二个是url地址 //ServletRegistrationBean bean = //new ServletRegistrationBean( new MyServlet(),"/myservlet"); ServletRegistrationBean bean = new ServletRegistrationBean(); bean.setServlet( new MyServlet()); bean.addUrlMappings("/login","/test"); // <url-pattern> return bean; }}
3.3 过滤器Filter
Filter是Servlet标准中的过滤器,能够解决申请, 对申请的参数, 属性进行调整。 经常在过滤器中解决字符编码
在框架中应用过滤器:
- 创立自定义过滤器类
- 注册Filter过滤器对象
例子:
// 自定义过滤器public class MyFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("执行了MyFilter,doFilter "); filterChain.doFilter(servletRequest,servletResponse); }}
注册Filter
@Configurationpublic class WebApplicationConfig { @Bean public FilterRegistrationBean filterRegistrationBean(){ FilterRegistrationBean bean = new FilterRegistrationBean(); bean.setFilter( new MyFilter()); bean.addUrlPatterns("/user/*"); return bean; }}
3.4 字符集过滤器
CharacterEncodingFilter : 解决post申请中乱码的问题
在SpringMVC框架, 在web.xml 注册过滤器。 配置他的属性。
第一种形式:
应用步骤:
配置字符集过滤器
@Configurationpublic 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 作用是关闭系统中配置好的过滤器, 应用自定义的CharacterEncodingFilterserver.servlet.encoding.enabled=false
第二种形式
批改application.properties文件
server.port=9001server.servlet.context-path=/myboot#让零碎的CharacterEncdoingFilter失效server.servlet.encoding.enabled=true#指定应用的编码方式server.servlet.encoding.charset=utf-8#强制request,response都应用charset属性的值server.servlet.encoding.force=true
第四章 ORM 操作 MySQL
应用MyBatis框架操作数据, 在SpringBoot框架集成MyBatis
应用步骤:
- mybatis起步依赖 : 实现mybatis对象主动配置, 对象放在容器中
- pom.xml 指定把src/main/java目录中的xml文件蕴含到classpath中
- 创立实体类Student
- 创立Dao接口 StudentDao , 创立一个查问学生的办法
- 创立Dao接口对应的Mapper文件, xml文件, 写sql语句
- 创立Service层对象, 创立StudentService接口和他的实现类。 去dao对象的办法。实现数据库的操作
- 创立Controller对象,拜访Service。
写application.properties文件
配置数据库的连贯信息。
第一种形式 : @Mapper
@Mapper:放在dao接口的下面, 每个接口都须要应用这个注解。
/** * @Mapper:通知MyBatis这是dao接口,创立此接口的代理对象。 * 地位:在类的下面 */@Mapperpublic interface StudentDao { Student selectById(@Param("stuId") Integer id);}
第二种形式 @MapperScan
/** * @MapperScan: 找到Dao接口和Mapper文件 * basePackages:Dao接口所在的包名 */@SpringBootApplication@MapperScan(basePackages = {"com.bjpowernode.dao","com.bjpowernode.mapper"})public class Application {}
第三种形式: Mapper文件和Dao接口离开治理
当初把Mapper文件放在resources目录下
1)在resources目录中创立子目录 (自定义的) , 例如mapper
2)把mapper文件放到 mapper目录中
3)在application.properties文件中,指定mapper文件的目录
#指定mapper文件的地位mybatis.mapper-locations=classpath:mapper/*.xml#指定mybatis的日志mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
4) 在pom.xml中指定 把resources目录中的文件 , 编译到目标目录中
<!--resources插件--><resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.*</include> </includes> </resource></resources>
第四个 事务
Spring框架中的事务:
1) 治理事务的对象: 事务管理器(接口, 接口有很多的实现类)
例如:应用Jdbc或mybatis拜访数据库,应用的事务管理器:DataSourceTransactionManager
2 ) 申明式事务: 在xml配置文件或者应用注解阐明事务管制的内容
管制事务: 隔离级别,流传行为, 超时工夫
3)事务处理形式:
1) Spring框架中的@Transactional
2) aspectj框架能够在xml配置文件中,申明事务管制的内容
SpringBoot中应用事务: 下面的两种形式都能够。
1)在业务办法的下面退出@Transactional , 退出注解后,办法有事务性能了。
2)明确的在 主启动类的下面 ,退出@EnableTransactionManager
例子:
/** * @Transactional: 示意办法的有事务反对 * 默认:应用库的隔离级别, REQUIRED 流传行为; 超时工夫 -1 * 抛出运行时异样,回滚事务 */@Transactional@Overridepublic int addStudent(Student student) { System.out.println("业务办法addStudent"); int rows = studentDao.insert(student); System.out.println("执行sql语句"); //抛出一个运行时异样, 目标是回滚事务 //int m = 10 / 0 ; return rows;}
第五章 接口架构格调 —RESTful
接口: API(Application Programming Interface,利用程序接口)是一些事后定义的接口(如函数、HTTP接口),或指软件系统不同组成部分连接的约定。 用来提供应用程序与开发人员基于某软件或硬件得以拜访的一组例程,而又无需拜访源码,或了解外部工作机制的细节。
接口(API): 能够指拜访servlet, controller的url, 调用其余程序的 函数
架构格调: api组织形式(样子)
就是一个传统的: http://localhost:9002/mytrans...
在地址上提供了 拜访的资源名称addStudent, 在其后应用了get形式传递参数。
5.1 REST
RESTful架构格调
1)REST : (英文: Representational State Transfer , 中文: 体现层状态转移)。
REST:是一种接口的架构格调和设计的理念,不是规范。
长处: 更简洁,更有档次
体现层状态转移:
体现层就是视图层, 显示资源的, 通过视图页面,jsp等等显示操作资源的后果。
状态: 资源变动
转移: 资源能够变动的。 资源能创立,new状态, 资源创立后能够查问资源, 能看到资源的内容,
这个资源内容 ,能够被批改, 批改后资源 和之前的不一样。
2)REST中的因素:
用REST示意资源和对资源的操作。 在互联网中,示意一个资源或者一个操作。
资源应用url示意的, 在互联网, 应用的图片,视频, 文本,网页等等都是资源。
资源是用名词示意。
对资源:
查问资源: 看,通过url找到资源。
创立资源: 增加资源
更新资源:更新资源 ,编辑
删除资源: 去除
资源应用url示意,通过名词示意资源。
在url中,应用名词示意资源, 以及拜访资源的信息, 在url中,应用“ / " 分隔对资源的信息
http://localhost:8080/myboot/...
应用http中的动作(申请形式), 示意对资源的操作(CURD)
GET: 查问资源 -- sql select
解决单个资源: 用他的复数形式
http://localhost:8080/myboot/...
http://localhost:8080/myboot/...
解决多个资源:应用复数模式
http://localhost:8080/myboot/...
POST: 创立资源 -- sql insert
http://localhost:8080/myboot/...
在post申请中传递数据
<form action="http://localhost:8080/myboot/student" method="post"> 姓名:<input type="text" name="name" /> 年龄:<input type="text" name="age" /> </form>
PUT: 更新资源 -- sql update
<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>
DELETE: 删除资源 -- sql delete
<a href="http://localhost:8080/myboot/student/1">删除1的数据</a>
须要的分页, 排序等参数,仍然放在 url的前面, 例如
http://localhost:8080/myboot/...
`
3) 一句话阐明REST:
应用url示意资源 ,应用http动作操作资源。
4) 注解
@PathVariable : 从url中获取数据
@GetMapping: 反对的get申请形式, 等同于 @RequestMapping( method=RequestMethod.GET)
@PostMapping: 反对post申请形式 ,等同于 @RequestMapping( method=RequestMethod.POST)
@PutMapping: 反对put申请形式, 等同于 @RequestMapping( method=RequestMethod.PUT)
@DeleteMapping: 反对delete申请形式, 等同于 @RequestMapping( method=RequestMethod.DELETE)
@RestController: 合乎注解, 是@Controller 和@ResponseBody组合。
在类的下面应用@RestController , 示意以后类者的所有办法都退出了 @ResponseBody
5) Postman : 测试工具
应用Postman : 能够测试 get ,post , put ,delete 等申请
5.2 在页面中或者ajax中,反对put,delete申请
在SpringMVC中 有一个过滤器, 反对post申请转为put ,delete
过滤器: org.springframework.web.filter.HiddenHttpMethodFilter
作用: 把申请中的post申请转为 put , delete
实现步骤:
- application.properties(yml) : 开启应用 HiddenHttpMethodFilter 过滤器
- 在申请页面中,蕴含 _method参数, 他的值是 put, delete , 发动这个申请应用的post形式
第六章 Redis
Redis : 一个NoSQL数据库, 罕用作 缓存应用 (cache)
Redis的数据类型: string , hash ,set ,zset , list
Redis是一个中间件: 是一个独立的服务器。
java中驰名的客户端: Jedis , lettuce , Redisson
Spring,SpringBoot中有 一个RedisTemplate(StringRedisTemplate) ,解决和redis交互
6.1 配置Windows版本的redis
Redis-x64-3.2.100.rar 解压缩到一个 非中文 的目录
redis-server.exe:服务端, 启动后,不要敞开
redis-cli.exe:客户端, 拜访redis中的数据
redisclient-win32.x86_64.2.0.jar : Redis图形界面客户端
执行形式: 在这个文件所在的目录, 执行 java -jar redisclient-win32.x86_64.2.0.jar
RedisTemplate 应用的 lettuce 客户端库
<!--redis起步依赖: 间接在我的项目中应用RedisTemplate(StringRedisTemplate)--><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId></dependency>data-redis应用的 lettuce 客户端库在程序中应用RedisTemplate类的办法 操作redis数据, 理论就是调用的lettuce 客户端的中的办法
6.2 比照 StringRedisTemplate 和 RedisTemplate
StringRedisTemplate : 把k,v 都是作为String解决, 应用的是String的序列化 , 可读性好
RedisTemplate : 把k,v 通过了序列化存到redis。 k,v 是序列化的内容, 不能间接辨认.
默认应用的jdk序列化, 能够批改为前提的序列化
序列化:把对象转化为可传输的字节序列过程称为序列化。
反序列化:把字节序列还原为对象的过程称为反序列化。
为什么须要序列化
序列化最终的目标是为了对象能够跨平台存储,和进行网络传输。而咱们进行跨平台存储和网络传输的形式就是IO,而咱们的IO反对的数据格式就是字节数组。咱们必须在把对象转成字节数组的时候就制订一种规定(序列化),那么咱们从IO流外面读出数据的时候再以这种规定把对象还原回来(反序列化)。
什么状况下须要序列化
通过下面我想你曾经晓得了但凡须要进行“跨平台存储”和”网络传输”的数据,都须要进行序列化。
实质上存储和网络传输 都须要通过 把一个对象状态保留成一种跨平台辨认的字节格局,而后其余的平台才能够通过字节信息解析还原对象信息。
序列化的形式
序列化只是一种拆装组装对象的规定,那么这种规定必定也可能有多种多样,比方当初常见的序列化形式有:
JDK(不反对跨语言)、JSON、XML、Hessian、Kryo(不反对跨语言)、Thrift、Protofbuff、
Student( name=zs, age=20) ---- { "name":"zs", "age":20 }
java的序列化: 把java对象转为byte[], 二进制数据
json序列化:json序列化性能将对象转换为 JSON 格局或从 JSON 格局转换对象。例如把一个Student对象转换为JSON字符串{"name":"李四", "age":29} ),反序列化(将JSON字符串 {"name":"李四", "age":29} 转换为Student对象)
设置key或者value的序列化形式
// 应用RedisTemplate ,在存取值之前,设置序列化// 设置 key 应用String的序列化redisTemplate.setKeySerializer( new StringRedisSerializer());// 设置 value 的序列化redisTemplate.setValueSerializer( new StringRedisSerializer());redisTemplate.opsForValue().set(k,v);
第七章 SpringBoot集成Dubbo
7.1 看 SpringBoot继承Dubbo的文档
https://github.com/apache/dub...
7.2 公共我的项目
独立的maven我的项目: 定义了接口和数据类
public class Student implements Serializable { private static final long serialVersionUID = 1901229007746699151L; private Integer id; private String name; private Integer age;}public interface StudentService { Student queryStudent(Integer id);}
7.3 提供者
创立SpringBoot我的项目
1) pom.xml
<dependencies> <!--退出公共我的项目的gav--> <dependency> <groupId>com.bjpowernode</groupId> <artifactId>022-interface-api</artifactId> <version>1.0.0</version> </dependency> <!--dubbo依赖--> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.8</version> </dependency> <!--zookeeper依赖--> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-dependencies-zookeeper</artifactId> <version>2.7.8</version> <type>pom</type> <exclusions> <!-- 排除log4j依赖 --> <exclusion> <artifactId>slf4j-log4j12</artifactId> <groupId>org.slf4j</groupId> </exclusion> </exclusions> </dependency></dependencies>
2)实现接口
/** * 应用dubbo中的注解裸露服务 * @Component 能够不必加 */@DubboService(interfaceClass = StudentService.class,version = "1.0",timeout = 5000)public class StudentServiceImpl implements StudentService { @Override public Student queryStudent(Integer id) { Student student = new Student(); if( 1001 == id){ student.setId(1001); student.setName("------1001-张三"); student.setAge(20); } else if(1002 == id){ student.setId(1002); student.setName("#######1002-李四"); student.setAge(22); } return student; }}
3)application.properties
#配置服务名称 dubbo:application name="名称"spring.application.name=studentservice-provider#配置扫描的包, 扫描的@DubboServicedubbo.scan.base-packages=com.bjpowernode.service#配置dubbo协定#dubbo.protocol.name=dubbo#dubbo.protocol.port=20881#注册核心dubbo.registry.address=zookeeper://localhost:2181
4)在启动类的下面
@SpringBootApplication@EnableDubbopublic class ProviderApplication { public static void main(String[] args) { SpringApplication.run(ProviderApplication.class, args); }}
7.4消费者
创立SpringBoot我的项目
1) pom.xml
<dependencies> <!--退出公共我的项目的gav--> <dependency> <groupId>com.bjpowernode</groupId> <artifactId>022-interface-api</artifactId> <version>1.0.0</version> </dependency> <!--dubbo依赖--> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.8</version> </dependency> <!--zookeeper依赖--> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-dependencies-zookeeper</artifactId> <version>2.7.8</version> <type>pom</type> <exclusions> <!-- 排除log4j依赖 --> <exclusion> <artifactId>slf4j-log4j12</artifactId> <groupId>org.slf4j</groupId> </exclusion> </exclusions> </dependency></dependencies>
2) 创立了Controller 或者 Service都能够
@RestControllerpublic class DubboController { /** * 援用近程服务, 把创立好的代理对象,注入给studentService */ //@DubboReference(interfaceClass = StudentService.class,version = "1.0") /** * 没有应用interfaceClass,默认的就是 援用类型的 数据类型 */ @DubboReference(version = "1.0") private StudentService studentService; @GetMapping("/query") public String queryStudent(Integer id){ Student student = studentService.queryStudent(id); return "调用近程接口,获取对象:"+student; }}
3)application.properties
#指定服务名称spring.application.name=consumer-application#指定注册核心dubbo.registry.address=zookeeper://localhost:2181
7.5 练习
应用的技术: SpringBoot ,Dubbo, Redis, MyBatis
Student表:
[外链图片转存失败,源站可能有防盗链机制,倡议将图片保留下来间接上传(img-wjofTbqS-1645599534521)(D:\course\25-SpringBoot\笔记\images\image-20210119150418295.png)]
CREATE TABLE student
(id
int(11) NOT NULL AUTO_INCREMENT,name
varchar(255) COLLATE utf8_bin DEFAULT NULL,phone
varchar(11) COLLATE utf8_bin DEFAULT NULL,age
int(11) DEFAULT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
1) 注册学生
phone必须惟一, 如果曾经存在了手机号, 注册失败的。
int addStudent(Student student);
返回值:int
1: 注册胜利
2 : 手机号曾经存在
name至多两个字符,
age 必须 大于 0
2) 查问学生,依据id查问,此学生。
先到redis查问学生, 如果redis没有此学生,从数据库查问, 把查问到的学生放入到redis。
前面再次查问这个学生应该从redis就能获取到。
Student queryStudent(Integer id);
3) 应用Dubbo框架, addStudent, queryStudent 是有服务提供者实现的。
消费者能够是一个Controller , 调用提供者的两个办法。 实现注册和查问。
4)页面应用html和ajax,jquery。
在html页面中提供 form 注册学生, 提供文本框输出id,进行查问。
注册和查问都应用ajax技术。
html,jquery.js都放到resources/static目录中
第八章 打包
8.1 打包war
1.创立了一个jsp利用
2.批改pom.xml
1)指定打包后的文件名称
<build> <!--打包后的文件名称--> <finalName>myboot</finalName></build>
2)指定jsp编译目录
<!--resources插件, 把jsp编译到指定的目录--><resources> <resource> <directory>src/main/webapp</directory> <targetPath>META-INF/resources</targetPath> <includes> <include>**/*.*</include> </includes> </resource> <!--应用了mybatis ,而且mapper文件放在src/main/java目录--> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> <!--把src/main/resources上面的所有文件,都蕴含到classes目录--> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.*</include> </includes> </resource></resources>
3)执行打包是war
<!--打包类型--><packaging>war</packaging>
4)主启动类继承SpringBootServletInitializer
/** * SpringBootServletInitializer: 继承这个类, 能力应用独立tomcat服务器 */@SpringBootApplicationpublic 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); }}
5)部署war
把war放到tomcat等服务器的公布目录中。 tomcat为例, myboot.war放到tomcat/webapps目录。
8.2 打包为jar
1.创立了一个蕴含了jsp的我的项目
2.批改pom.xml
1) 指定打包后的文件名称
<build> <!--打包后的文件名称--> <finalName>myboot</finalName></build>
2) 指定springboot-maven-plugin版本
<plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <!--打包jar, 有jsp文件时,必须指定maven-plugin插件的版本是 1.4.2.RELEASE--> <version>1.4.2.RELEASE</version> </plugin></plugins>
3)最初执行 maven clean package
在target目录中,生成jar 文件, 例子是myboot.jar
执行独立的springboot我的项目 在cmd中 java -jar myboot.jar
第九章 Thymeleaf 模板引擎
Thymeleaf: 是应用java开发的模板技术, 在服务器端运行。 把解决后的数据发送给浏览器。
模板是作视图层工作的。 显示数据的。 Thymeleaf是基于Html语言。 Thymleaf语法是利用在
html标签中 。 SpringBoot框架集成Thymealeaf, 应用Thymeleaf代替jsp。
Thymeleaf 的官方网站:http://www.thymeleaf.org
Thymeleaf 官网手册:https://www.thymeleaf.org/doc...
9.1 表达式
规范变量表达式
语法: ${key}
作用: 获取key对于的文本数据, key 是request作用域中的key , 应用request.setAttribute(), model.addAttribute()
在页面中的 html标签中, 应用 th:text="${key}"
<div style="margin-left: 400px"> <h3>规范变量表达式: ${key}</h3> <p th:text="${site}">key不存在</p> <br/> <p>获取SysUser对象 属性值</p> <p th:text="${myuser.id}">id</p> <p th:text="${myuser.name}">姓名</p> <p th:text="${myuser.sex}">姓名:m男</p> <p th:text="${myuser.age}">年龄</p> <p th:text="${myuser.getName()}">获取姓名应用getXXX</p></div>
抉择变量表达式( 星号变量表达式)
语法: *{key}
作用: 获取这个key对应的数据, *{key}须要和th:object 这个属性一起应用。
目标是简略获取对象的属性值。
<p>应用 *{} 获取SysUser的属性值</p><div th:object="${myuser}"> <p th:text="*{id}"></p> <p th:text="*{name}"></p> <p th:text="*{sex}"></p> <p th:text="*{age}"></p></div><p>应用*{}实现的示意 对象的属性值</p><p th:text="*{myuser.name}" ></p>
链接表达式
语法: @{url}
作用: 示意链接, 能够
<script src="..."> , <link href="..."> <a href=".."> ,<form action="..."> <img src="...">
9.2 Thymeleaf属性
属性是放在html元素中的,就是html元素的属性,退出了th前缀。 属性的作用不变。 退出上th, 属性的值由模板引擎解决了。 在属性能够应用变量表达式
例如:
<form action="/loginServlet" method="post"></form><form th:action="/loginServlet" th:method="${methodAttr}"></form>
9.3 each
each循环, 能够循环List,Array
语法:
在一个html标签中,应用th:each
<div th:each="汇合循环成员,循环的状态变量:${key}"> <p th:text="${汇合循环成员}" ></p></div>汇合循环成员,循环的状态变量:两个名称都是自定义的。 “循环的状态变量”这个名称能够不定义,默认是"汇合循环成员Stat"
each循环Map
在一个html标签中,应用th:each
<div th:each="汇合循环成员,循环的状态变量:${key}"> <p th:text="${汇合循环成员.key}" ></p> <p th:text="${汇合循环成员.value}" ></p></div>汇合循环成员,循环的状态变量:两个名称都是自定义的。 “循环的状态变量”这个名称能够不定义,默认是"汇合循环成员Stat"key:map汇合中的keyvalue:map汇合key对应的value值
9.4 th:if
"th:if" : 判断语句, 当条件为true, 显示html标签体内, 反之不显示 没有else语句
语法:<div th:if=" 10 > 0 "> 显示文本内容 </div>
还有一个 th:unless 和 th:if相同的行为
语法:<div th:unless=" 10 < 0 "> 当条件为false显示标签体内容 </div>
例子:if
<div style="margin-left: 400px"> <h3> if 应用</h3> <p th:if="${sex=='m'}">性别是男</p> <p th:if="${isLogin}">曾经登录零碎</p> <p th:if="${age > 20}">年龄大于20</p> <!--""空字符是true--> <p th:if="${name}">name是“”</p> <!--null是false--> <p th:if="${isOld}"> isOld是null</p> </div>
例子: unless
<div style="margin-left: 400px"> <h3>unless: 判断条件为false,显示标签体内容</h3> <p th:unless="${sex=='f'}">性别是男的</p> <p th:unless="${isLogin}">登录零碎</p> <p th:unless="${isOld}"> isOld是null </p> </div>
9.5 th:switch
th:switch 和 java中的swith一样的
语法:<div th:switch="要比对的值"> <p th:case="值1"> 后果1 </p> <p th:case="值2"> 后果2 </p> <p th:case="*"> 默认后果 </p> 以上的case只有一个语句执行 </div>
9.6 th:inline
内联text: 在html标签外,获取表达式的值
语法:
<p>显示姓名是:[[${key}]]</p> <div style="margin-left: 400px"> <h3>内联 text, 应用内联表达式显示变量的值</h3> <div th:inline="text"> <p>我是[[${name}]],年龄是[[${age}]]</p> 我是<span th:text="${name}"></span>,年龄是<span th:text="${age}"></span> </div> <div> <p>应用内联text</p> <p>我是[[${name}]],性别是[[${sex}]]</p> </div></div>
- 内联javascript
例子: <script type="text/javascript" th:inline="javascript"> var myname = [[${name}]]; var myage = [[${age}]]; //alert("获取的模板中数据 "+ myname + ","+myage) function fun(){ alert("单击事件,获取数据 "+ myname + ","+ [[${sex}]]) } </script>
9.7 字面量
例子:
<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>
9.8 字符串连贯
连贯字符串有两种语法
1) 语法应用 单引号括起来字符串 , 应用 + 连贯其余的 字符串或者表达式
<p th:text="'我是'+${name}+',我所在的城市'+${city}">数据显示</p>
2)语法:应用双竖线, |字符串和表达式|
<p th:text="|我是${name},我所在城市${city|"> 显示数据</p>
例子:
<div style="margin-left: 400px"> <h3>字符串连贯形式1:应用单引号括起来的字符串</h3> <p th:text="'我是'+${name}+',我所在的城市'+${city}">数据显示</p> <br/> <br/> <h3>字符串连贯形式2:|字符串和表达式|</h3> <p th:text="|我是${name},所在城市${city},其他人${myuser.name}|"></p> </div>
9.9 运算符
算术运 算: + , - - , * , / , %关系比拟 : > , < , >= , <= ( gt , lt , ge , le )相等判断: == , != ( eq , ne )<div style="margin-left: 400px"> <h3>应用运算符</h3> <p th:text="${age > 10}">年龄大于 10 </p> <p th:text="${ 20 + 30 }">显示运算后果</p> <p th:if="${myuser == null}">myuser是null</p> <p th:if="${myuser eq null}">myuser是null</p> <p th:if="${myuser ne null}">myuser不是null</p> <p th:text="${isLogin == true ? '用户曾经登录' : '用户须要登录'}"></p> <p th:text="${isLogin == true ? ( age > 10 ? '用户是大于10的' : '用户年龄比拟小') : '用户须要登录'}"></p> </div>三元运算符: 表达式 ? true的后果 : false的后果三元运算符能够嵌套
9.10 内置对象
文档地址:https://www.thymeleaf.org/doc...
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>
9.11 内置工具类
内置工具类型: 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</h3> <p th:text="${zoo?.dog?.name}"></p> </div>
9.12 自定义模板
模板是内容复用, 定义一次,在其余的模板文件中屡次应用。
模板应用:
1.定义模板
2.应用模板
模板定义语法:
th:fragment="模板自定义名称"例如:<div th:fragment="head"> <p> 能源节点-java开发 </p> <p> www.bjpowernode.com </p></div>
援用模板语法:
1) ~{templatename :: selector} templatename: 文件名称 selector: 自定义模板名称2)templatename :: selector templatename: 文件名称 selector: 自定义模板名称对于应用模板:有蕴含模板(th:include), 插入模板(th:insert)
第十章 总结
10.1 注解
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性能。
援用模板语法:
1) ~{templatename :: selector} templatename: 文件名称 selector: 自定义模板名称2)templatename :: selector templatename: 文件名称 selector: 自定义模板名称对于应用模板:有蕴含模板(th:include), 插入模板(th:insert)
第十章 总结
10.1 注解
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性能。