SpringBoot
資料官方下載:動力節點官網
視頻觀看地址
https://www.bilibili.com/video/BV1XQ4y1m7ex
第一章 JavaConfig
為什么要使用 Spring Boot?
1. 因為Spring, SpringMVC 需要使用的大量的組態檔 (xml檔案)
還需要配置各種物件,把使用的物件放入到spring容器中才能使用物件
需要了解其他框架配置規則,
2. SpringBoot 就相當于 不需要組態檔的Spring+SpringMVC, 常用的框架和第三方庫都已經配置好了,
拿來就可以使用了,
3. 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="https://www.cnblogs.com/daoshangmazai/archive/2022/01/20/${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專案的結構:
2.2.1 使用國內的地址
https://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.bjpower.com school.address=北京的大興區 site=www.bjpower.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()方法,
可以完成自定義的在容器物件創建好的一些操作,
@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的請求,
攔截器框架中有系統的攔截器, 還可以自定義攔截器, 實作對請求預先處理,
實作自定義攔截器:
1. 創建類實作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的組態檔中,宣告攔截器
xml <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 注冊過濾器, 配置他的屬性,
第一種方式:
使用步驟:
1. 配置字符集過濾器
@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; } }
2. 修改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
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 @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="https://www.cnblogs.com/daoshangmazai/archive/2022/01/20/PUT" /> </form>
DELETE: 洗掉資源 – sql delete
xml
洗掉1的資料
需要的分頁, 排序等引數,依然放在 url的后面, 例如
http://localhost:8080/myboot/students?page=1&pageSize=20
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/dubbo-spring-boot-project/blob/master/README_CN.md
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>
2)創建了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);
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服務器 */ @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
? 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/tutorials/3.0/usingthymeleaf.html
9.1 運算式
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>
2. 選擇變數運算式( 星號變數運算式)
語法: *{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>
3. 鏈接運算式
語法: @{url}
作用: 表示鏈接, 可以
<script src="https://www.cnblogs.com/daoshangmazai/archive/2022/01/20/..."> , <link href="https://www.cnblogs.com/daoshangmazai/archive/2022/01/20/..."> <a href="https://www.cnblogs.com/daoshangmazai/archive/2022/01/20/.."> ,<form action="..."> <img src="https://www.cnblogs.com/daoshangmazai/archive/2022/01/20/...">
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
1. 行內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>
2. 行內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/tutorials/3.0/usingthymeleaf.html#web-context-namespaces-for-requestsession-attributes-etc.
#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.
</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功能,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/417058.html
標籤:其他
