敞开生长之旅!这是我参与「日新方案 12 月更文挑战」的第12天,点击检查活动详情
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
*/
@Configuration
public 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运用
运用的地址: start.spring.io
SpringBoot项目的结构:
2.2.1 运用国内的地址
start.springboot.io
2.3 注解的运用
@SpringBootApplication
契合注解:由
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
1.@SpringBootConfiguration
@Configuration
public @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
#设置拜访运用上下文途径, contextpath
server.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-path
server.servlet.context-path=/myboot
#自界说key=value
school.name=动力节点
school.website=www.bjpowernode.com
school.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>
- 假如需求运用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
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()办法。
能够完成自界说的在容器目标创立好的一些操作。
@FunctionalInterface
public interface CommandLineRunner {
void run(String... args) throws Exception;
}
@FunctionalInterface
public 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中注册阻拦器:
@Configuration
public 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
@Configuration
public 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
@Configuration
public 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 注册过滤器。 装备他的特点。
第一种办法:
运用进程:
-
装备字符集过滤器
@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
第二种办法
修正application.properties文件
server.port=9001
server.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接口,创立此接口的署理目标。
* 方位:在类的上面
*/
@Mapper
public 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
- 在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
- aspectj结构能够在xml装备文件中,声明业务操控的内容
SpringBoot中运用业务: 上面的两种办法都能够。
1)在业务办法的上面参加@Transactional , 参加注解后,办法有业务功用了。
2)清晰的在 主发动类的上面 ,参加@EnableTransactionManager
比方:
/**
* @Transactional: 表明办法的有业务支撑
* 默许:运用库的阻隔级别, REQUIRED 传播行为; 超时时刻 -1
* 抛出运行时异常,回滚业务
*/
@Transactional
@Override
public 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?name=lisi&age=26
在地址上供给了 拜访的资源称号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/student/1001
运用http中的动作(恳求办法), 表明对资源的操作(CURD)
GET: 查询资源 — sql select
处理单个资源: 用他的奇数办法
http://localhost:8080/myboot/student/1001
http://localhost:8080/myboot/student/1001/1
处理多个资源:运用复数形式
http://localhost:8080/myboot/students/1001/1002
POST: 创立资源 — sql insert
http://localhost:8080/myboot/student
在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
```xml
删去1的数据 “`
需求的分页, 排序等参数,仍然放在 url的后边, 例如
http://localhost:8080/myboot/students?page=1&pageSize=20
`
3) 一句话阐明REST:
运用url表明资源 ,运用http动作操作资源。
- 注解
@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
-
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的文档
github.com/apache/dubb…
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
#装备扫描的包, 扫描的@DubboService
dubbo.scan.base-packages=com.bjpowernode.service
#装备dubbo协议
#dubbo.protocol.name=dubbo
#dubbo.protocol.port=20881
#注册中心
dubbo.registry.address=zookeeper://localhost:2181
4)在发动类的上面
@SpringBootApplication
@EnableDubbo
public 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>
- 创立了Controller 或许 Service都能够
@RestController
public 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表:
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;
- 注册学生
phone有必要唯一, 假如现已存在了手机号, 注册失利的。
int addStudent(Student student);
返回值:int
1: 注册成功
2 : 手机号现已存在
name至少两个字符,
age 有必要 大于 0
2) 查询学生,根据id查询,此学生。
先到redis查询学生, 假如redis没有此学生,从数据库查询, 把查询到的学生放入到redis。
后边再次查询这个学生应该从redis就能获取到。
Student queryStudent(Integer id);
- 运用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服务器
*/
@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);
}
}
5)部署war
把war放到tomcat等服务器的发布目录中。 tomcat为例, myboot.war放到tomcat/webapps目录。
8.2 打包为jar
1.创立了一个包括了jsp的项目
2.修正pom.xml
- 指定打包后的文件称号
<build>
<!--打包后的文件称号-->
<finalName>myboot</finalName>
</build>
- 指定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 的官方网站:www.thymeleaf.org Thymeleaf 官方手册:www.thymeleaf.org/doc/tutoria…
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调集中的key
value: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 内置目标
文档地址:www.thymeleaf.org/doc/tutoria….
#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功用。