當前互聯網後端開發中,JavaEE佔據了主導地位。對JavaEE開發,首選框架是Spring框架。在傳統的Spring開發中,須要使用大量的與業務無關的XML配置才能使Spring框架運行起來,這點備受許多開發者詬病。隨着Spring4.x發佈,Spring已經徹底脫離XML,只使用註解就能夠運行項目。爲了進一步簡化Spring應用的開發,SpringBoot誕生了。它是由Pivotal團隊提供的全新框架,其設計目的是簡化Spring應用的搭建及開發過程,並迎合時下流行的分佈式微服務設計思想,愈來愈多企業在使用SpringBoothtml
SpringBoot爲咱們開發者提供了一種更快速、體驗更好的開發方式,咱們能夠開箱即用,無需像寫Spring那樣配置各類XML文件,雖然Spring3.0時引入了基於java的配置,可是編寫這些配置無疑是在浪費大量時間,其實SpringBoot還內置Tomcatjava
一:獨立的運行Spring SpringBoot 能夠以jar包形式獨立運行,運行一個SpringBoot項目只須要經過java -jar xx.jar來運行 二:內置Servlet容器 Spring Boot能夠選擇內嵌Tomcat、jetty或者Undertow,這樣咱們無須以war包形式部署項目 三:簡化Maven配置 SpringBoot提供了一系列的start pom來簡化Maven的依賴加載,例如,當你使用了spring-boot-starter-web 四:自動裝配 SpringBoot會根據在類路徑中的jar包,類、爲jar包裏面的類自動配置Bean,這樣會極大地減小咱們要使用的配置。
固然,SpringBoot只考慮大多數的開發場景,並非全部的場景,若在實際開發中咱們須要配置Bean,而SpringBoot
沒有提供支持,則能夠自定義自動配置 五:準生產的應用監控 SpringBoot提供基於http ssh telnet對運行時的項目進行監控 六:無代碼生產和xml配置 SpringBoot不是藉助與代碼生成來實現的,而是經過條件註解來實現的,這是Spring4.x提供的新特性
Spring Boot只是Spring自己的擴展,使開發,測試和部署更加方便mysql
SpringBoot 2.4.1正式發行版,要求Java8而且兼容Java15;對應的Spring版本是5.3.2;並且要求Maven 3.3+ 可是最好使用3.5.4穩定版本,而Servlet容器的版本爲Tomcat9.0(Servlet Version 4.0)、Jetty 9.4(Servlet Version 3.1)、Undertow 2.0(Servlet Version 4.0) web
咱們以一個簡單的SpringBoot案例來突顯出Spring的繁瑣,我接下來將使用SpringBoot來實現一個簡單的帶Controller的案例redis
第一步:使用IDEA構建一個普通的Maven項目
第二步:在構建好的maven工程中對pom文件修改
第三步:編寫啓動引導類
第四步:編寫Controller
第五步:訪問(默認8080端口) 以本案例http://localhost:8080/index/test
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!-- 在編寫SpringBoot的項目時咱們得繼承SpringBoot的父POM文件, 這一點和咱們之前使用Spring導入的座標不太同樣,細心的會查看 繼承的父POM文件後發現SpringBoot爲咱們提早導入了大量的座標, 這就解決了咱們日常導入座標版本衝突問題 --> <parent> <artifactId>spring-boot-starter-parent</artifactId> <groupId>org.springframework.boot</groupId> <version>2.4.1</version> </parent> <groupId>org.example</groupId> <artifactId>demo0023</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!-- 要編寫SpringMVC相關代碼咱們還得導入web的starter依賴 SpringBoot爲了咱們導入的方便,把一系列的關於SpringMVC的座標打包結合到了 這個我下面導入的座標裏面 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project>
package cn.xw; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * 啓動引導類 */ //加上此註解表明當前類就是SpringBoot啓動類,不然就是普通類 @SpringBootApplication public class SpringBoot5Application { //SpringBoot程序入口 public static void main(String[] args) { //main函數裏面的args參數是一個String數組,因此在main函數運行的 //同時能夠接收參數,接收過來的參數交給了SpringBoot,用於後期運行配置,後面介紹 //第一個參數經過反射是告訴SpringBoot哪一個是啓動引導類 //還有這個方法有個返回值,返回IOC容器 SpringApplication.run(SpringBoot5Application.class, args); } /** * 注意:此類只會掃描加載當前包及其子包裏面的所有類,然會把它們加載IOC容器中 */ }
package cn.xw.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController //結合@ResponseBody 和 @Controller 兩註解 @RequestMapping("/index") public class IndexController { @RequestMapping("/test") public String testMethod() { System.out.println("訪問到此方法"); return "Hello !!"; } }
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!--SpringBoot父POM座標--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.1</version> <relativePath/> </parent> <groupId>cn.xw</groupId> <artifactId>springboot_test</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springboot_test</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!--WEB開發Starter--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--SpringBoot的開發者工具--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <!--SpringBoot測試Starter--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <!--SpringBoot的Maven插件--> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
starter是依賴關係的整理和封裝。是一套依賴座標的整合,可讓導入應用開發的依賴座標更方便。利用依賴傳遞的特性幫咱們把一些列指定功能的座標打包成了一個starter,咱們只須要導入starter便可,無需導入大量座標;每一個Starter包含了當前功能下的許多必備依賴座標這些依賴座標是項目開發,上線和運行必須的。同時這些依賴也支持依賴傳遞。以下Starter:spring
<!--導入WEB開發Starter--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.4.1</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-json</artifactId> <version>2.4.1</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <version>2.4.1</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.3.2</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.2</version> <scope>compile</scope> </dependency> </dependencies>
封裝成各個Starter的好處就是讓咱們更加專一於業務開發,無需關心依賴導入,依賴衝突,及依賴的版本sql
問:爲何導入的一些Starter不須要寫版本呢?數據庫
不指定版本是由於maven有依賴傳遞的特性,可推測starter在父級定義了並鎖定了版本;spring-boot-dependencies.xml 文件能夠給你們一個答案;繼承關係爲 spring-boot-starter-parent.xml ==> spring-boot-dependencies.xml 這裏面鎖定了咱們經常使用的座標及Staterapache
編寫SpringBoot項目繼承spring-boot-starter-parent的好處和特色編程
①:默認編譯Java 1.8
②:默認編碼UTF-8
③:經過spring-boot-denpendencies的pom管理全部公共Starter依賴的版本
④:spring-boot-denpendencies經過Maven的依賴傳遞和版本鎖定特性來實現版本管理
⑤:隨用隨取,不用繼承父類全部的starter依賴。
POM文件中的Maven插件功能
<build> <plugins> <!-- 做用:將一個SpringBoot的工程打包成爲可執行的jar包 --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
全部咱們要配置的項目Pivotal團隊的開發人員,幫咱們寫好了,怎麼實現的,主要是經過@Configuration實現 SpringBoot採用約定大於配置設計思想,將全部可能遇到的配置信息提早配置好,寫在自動配置的jar包中。每一個Starter基本都會有對應的自動配置。SpringBoot幫咱們將配置信息寫好,存放在一個jar包中:spring-boot-autoconfigure-2.4.1.jar;jar包裏,存放的都是配置類,讓配置類生效的"規則類"
接下來我來介紹一個咱們常見的配置類 一:找到項目的External Libraries 二:查找Maven:org.springframework.boot:spring-autoconfigue:2.4.1 三:內部有個spring-boot-autoconfigue-2.4.1.jar 四:點擊org ==> web ==> servlet ==> ServletWebServerFactoryAutoConfiguration類 @Configuration(proxyBeanMethods = false) //表明是個配置類 SpringBoot爲咱們提供的每一個配置類都有此註解 @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) @ConditionalOnClass(ServletRequest.class) @ConditionalOnWebApplication(type = Type.SERVLET) @EnableConfigurationProperties(ServerProperties.class) @Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, ServletWebServerFactoryConfiguration.EmbeddedTomcat.class, ServletWebServerFactoryConfiguration.EmbeddedJetty.class, ServletWebServerFactoryConfiguration.EmbeddedUndertow.class }) public class ServletWebServerFactoryAutoConfiguration { ... } 補充:咱們回到以前點擊META-INF ==> spring.factories 這裏面配置的是SpringBoot的所有配置類
補充:咱們回到以前點擊META-INF ==> spring-configuration-metadata.json 這裏面配置着各類配置類的信息參數
問:SpringBoot提供這麼多配置類,難道是程序運行後就所有導入嗎?
不會所有導入,只會根據當前項目的需求選擇性的裝配所需的配置類,這也是SpringBoot的自動裝配一大特性;咱們也能夠設想一下,一次性裝配所有配置類,那該多慢呀;
問:SpringBoot怎麼知道程序運行後就自動裝配呢?
咱們找到SpringBoot入口函數,點開 @SpringBootApplication 註解會發現裏面有個 @EnableAutoConfiguration 這個註解就是開啓自動配置的
問:開啓自動裝配後,它咋知道要加載指定配置呢?那麼多配置類呢
咱們繼續看上面的 ServletWebServerFactoryAutoConfiguration 配置類
@Configuration(proxyBeanMethods = false) @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) //配置類可否被自動裝配主要看 @ConditionalOnClass註解 //此註解是否能夠加載到一個叫 ServletRequest.class文件,一旦存在則自動裝配 @ConditionalOnClass(ServletRequest.class) @ConditionalOnWebApplication(type = Type.SERVLET) @EnableConfigurationProperties(ServerProperties.class) @Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, ServletWebServerFactoryConfiguration.EmbeddedTomcat.class, ServletWebServerFactoryConfiguration.EmbeddedJetty.class, ServletWebServerFactoryConfiguration.EmbeddedUndertow.class }) public class ServletWebServerFactoryAutoConfiguration { ... }
有了自動配置後,那麼基本所有采用默認配置(這也就是爲啥說約定大於配置的思想);那麼要修改默認配置也是能夠的,咱們只需在配置文件配置指定的參數便可 官方所有可配置屬性 以下常見配置:
# 端口配置 server.port=8888 # 配置context-path項目訪問根路徑 server.servlet.context-path=/demo # 開啓debug模式,詳細日誌輸出,用於開發的一種設置 默認是false debug=true # 配置日誌 logging.level.{指定包下的日誌}=debug logging.level.cn.xw=debug
SpringBoot是約定大於配置的,配置都有默認值。若是想修改默認配置,可使用application.properties或application.yml或application.yaml自定義配置。SpringBoot默認從Resource目錄加載自定義配置文件。application.properties是鍵值對類型;application.yml是SpringBoot中一種新的配置文件方式,在使用自定義配置時名稱必定要爲application,由於是提早約定好的,並且三個後綴名的文件都寫上是有個前後順序,後面可覆蓋前面
<includes> <include>**/application*.yml</include> <include>**/application*.yaml</include> <include>**/application*.properties</include> </includes>
# properties類型配置文件 application.properties server.port=8080 server.address=127.0.0.1 <!--xml類型配置文件 application.xml--> <server> <port>8080</port> <address>127.0.0.1</address> </server> # yml/yaml類型配置文件 application.yml/ymal server: port: 8080 address: 127.0.0.1
YML文件格式是YAML(YAML Aint Markup Language)編寫的文件格式。能夠直觀被電腦識別的格式。容易閱讀,容易與腳本語言交互。能夠支持各類編程語言(C/C++、Ruby、Python、Java、Perl、C#、PHP)。以數據爲核心,比XML更簡潔。擴展名爲.yml或.yaml 官方網站 在線properties轉yml
1:大小寫敏感 2:數據值前邊必須有空格,做爲分隔符 3:使用縮進表示層級關係 4:縮進不容許使用tab,只容許空格 5:縮進的空格數不重要,只要相同層級的元素左對齊便可 6:"#"表示註釋,從這個字符一直到行尾,都會被解析器忽略。 7:數組和集合使用 "-" 表示數組每一個元素
# 單個值指定 name: 小周 # 單引號忽略轉義字符 message1: 'hello \n world' # 雙引號識別轉義字符 打印時會換行 message2: "hello \n world" # 對象方式指定 普通寫法 student: name: 張三 age: 25 address: 安徽六安 # 對象方式指定 行內寫法 teacher: { name: 李老師, age: 50, address: 上海 } # 數組方式 普通寫法 hobby: - baseball - basketball - volleyball # 數組方式 行內寫法 likes: [ baseball, basketball, volleyball ] # 集合方式 map等格式 peoples: key1: zhangsan key2: anhui key3: xiezi # 集合方式 map等格式 行內寫法 peoples1: { key1 : zhangsan, key2 : anhui , key3 : shanghai} # 這上面的key~ 是具體的key名稱 ######## 其它方式擴展 # 配置引用 bookName: 零基礎學Java person: name: xiaowu likeBookName: ${bookName} # 配置隨機數 其中有int 和 long兩種根據狀況選擇 # 隨機字符串 StringA: ${random.value} # 隨機數 numberB: ${random.int} # 隨機產出小於10的數 numberC: ${random.int(10)} # 隨機產出10~100之間的數 大於10小於100 numberD: ${random.int(10,100)} # 隨機產出一個uuid字符串 uuid: ${random.uuid}
(1):java配置獲取基本的配置文件信息.properties類型
三:配置類 jdbcConfig.java //聲明此類爲配置類 @Configuration //導入外部配置文件 由於這個配置類是自定義的,不受SpringBoot幫咱們管理 @PropertySource(value="classpath:application.properties") public class JdbcConfig { @Value(value = "${jdbc.datasource.driver-class-name}") private String driver; @Value("${jdbc.datasource.url}") private String url; @Value("${jdbc.datasource.username}") private String username; @Value("${jdbc.datasource.password}") private String password; @Bean(value = "dataSource") public DataSource getDataSource() { System.out.println(driver); //建立鏈接池 並加入容器 DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(driver); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); return dataSource; } } 四:Controller 經過訪問運行程序 這裏就先不寫測試類 @RestController //結合@ResponseBody 和 @Controller 兩註解 @RequestMapping("/index") public class IndexController { @Autowired private DataSource dataSource; @RequestMapping("/test") public String testMethod() { System.out.println("訪問到此方法"+dataSource); return "Hello !!"; } } //打印 訪問到此方法{ CreateTime:"2021-01-09 15:22:49", ActiveCount:0, PoolingCount:0, CreateCount:0, DestroyCount:0, CloseCount:0, ConnectCount:0, Connections:[ ] }
(2):java配置獲取基本的配置文件信息並注入.yml/.yaml類型
1、使用註解@Value映射 @value註解將配置文件的值映射到Spring管理的Bean屬性值,只能映射基本數據類型 2、使用註解@ConfigurationProperties映射 經過註解@ConfigurationProperties(prefix=''配置文件中的key的前綴")能夠將配置文件中的配置自動與實體進行映射。
使用@ConfigurationProperties方式必須提供Setter方法,使用@Value註解不須要Setter方法
注:使用@ConfigurationProperties要在主函數上開啓@EnableConfigurationProperties
/** * @author: xiaofeng * @date: Create in $DATE * @description: 學生對象 * @version: v1.0.0 */ @Component //必定要保證被映射注入的是個組件 @ConfigurationProperties(prefix = "student") //能夠之間映射對象 public class Student { private Integer id; //id private String name; //姓名 private String address; //住宅 private List<String> hobbys; //愛好 private Map<String, List<Integer>> score;//各科得分 private Map<String,Teacher> teachers; //各科老師 //...省略get/set 這個必定要寫 我爲了代碼少沒複製 } /** * @author: xiaofeng * @date: Create in $DATE * @description: 老師對象 * @version: v1.0.0 */ public class Teacher { private String name; private String message; } //注:在添加完@ConfigurationProperties後若是沒有spring-boot-configuration-processor編譯器會彈出提示 //提示信息:Spring Boot Configuration Annotation Processor..... //pom.xml添加這個配置註解處理器 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> //而後去主函數類上面添加@EnableConfigurationProperties 開啓配置註解處理器
student: id: 1001 name: 張三 address: 安徽六安 hobbys: - baseball - basketball - volleyball score: yuwen: - 66 - 88 shuxue: - 85 - 99 #簡寫 score: { "yuwen" : [58,99], "shuxue" : [88,96] } # 這裏經過外界傳入值 注意引號別忘了 teachers: yuwenTeacher: { name: "${teacherNameA}", message: "${teacherMessageA}" } shuxueTecher: { name: "${teacherNameB}", message: "${teacherMessageB}" } teacherNameA: 張老師 teacherMessageA: 教語文 teacherNameB: 李老師 teacherMessageB: 教數學
//經過web的方式加載程序運行
@RestController //結合@ResponseBody 和 @Controller 兩註解 @RequestMapping("/index") public class IndexController { //注入 @Autowired private Student student; @RequestMapping("/test") public String testMethod() { System.out.println(student.toString()); //Student{ // id=1001, // name='張三', // address='安徽六安', // hobbys=[baseball, basketball, volleyball], // score={yuwen=[66, 88], shuxue=[85, 99]}, // teachers={yuwenTeacher=Teacher{name='張老師', message='教語文'}, // shuxueTecher=Teacher{name='李老師', message='教數學'}}} return "Hello !!"; } }
集成Mybatis完成查詢所有
(1):使用註解方式完成集成
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.1</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>cn.xw</groupId> <artifactId>demomybatiss</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demomybatiss</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!--web啓動器--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--spring-boot啓動器--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.4</version> </dependency> <!--工具--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <!--mysql驅動--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!--測試 這裏沒用到--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/demo_school?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC username: root password: 123 # 加上 ?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC 是爲了防止SpringBoot報時區錯誤 # com.mysql.jdbc.Driver 這種的已通過時了,可是不表明就剔除了 能夠用
///////////POJO /** * @author: xiaofeng * @date: Create in $DATE * @description: 學生實體類 * @version: v1.0.0 */ public class Student implements Serializable { private int id; //id private String name; //姓名 private String sex; //性別 private int age; //年齡 private double credit; //成績/學分 private double money; //零花錢 private String address; //住址 private String enrol; //入學時間 //private int fid; //外鍵 家庭 //private int tid; //外鍵 老師 //構造器(無參構造器必須有)/set/get/toString 大家補充一下 } /////////// Mapper //此註解org.apache.ibatis.annotations.Mapper 是mybatis提供的加入容器 //Mapper 能夠說等於 @Component、@Repository、@Server、@Controller @Mapper public interface StudentMapper { //查詢所有 @Select("select * from student") @Results(id = "studentMapper", value = { @Result(id = true, column = "sid", property = "id"), @Result(column = "sname", property = "name"), @Result(column = "ssex", property = "sex"), @Result(column = "sage", property = "age"), @Result(column = "scredit", property = "credit"), @Result(column = "smoney", property = "money"), @Result(column = "saddress", property = "address"), @Result(column = "senrol", property = "enrol") }) List<Student> findAll(); } ///////////Service /** * @author: xiaofeng * @date: Create in $DATE * @description: 學生業務接口 * @version: v1.0.0 */ public interface StudentService { //查詢所有 List<Student> findAll(); } /** * @author: xiaofeng * @date: Create in $DATE * @description: 學生業務實現 * @version: v1.0.0 */ @Service //注入到容器 public class StudentServiceImpl implements StudentService { //注入對象 若是是IDEA編譯器這邊會有個紅線錯誤,不影響 @Autowired private StudentMapper studentMapper; //查詢所有 @Override public List<Student> findAll() { return studentMapper.findAll(); } } //////////Controller @RestController @RequestMapping("/student") public class StudentController { @Autowired private StudentService studentService; @RequestMapping("/findAll") public List<Student> findAll() { System.out.println("訪問成功"); //這裏經過json把對象寫到瀏覽器,要序列化對象 return studentService.findAll(); } }
注:使用http://localhost:8080/student/findAll訪問,還有就是Mapper文件夾裏面的代碼必定要寫在主函數類當前包及其子包下,若是不在則須要在入口類添加@MapperScan或者@MapperScans註解掃描一下,這個是mybatis提供的
(2):使用Mapper.xml映射完成集成
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/demo_school?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC username: root password: 123 # spring繼承mybatis環境 # type-aliases-package:pojo別名掃描包 # mapper-locations:加載mybatis映射文件 mybatis: type-aliases-package: cn.xw.pojo mapper-locations: classpath:mapper/*Mapper.xml # 加上 ?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC 是爲了防止SpringBoot報時區錯誤 # com.mysql.jdbc.Driver 這種的已通過時了,可是不表明就剔除了 能夠用
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.xw.mapper.StudentMapper"> <!--名稱字段不同可使用這個映射名稱對應--> <resultMap id="studentMapper" type="student"> <id column="sid" property="id"/> <result column="sname" property="name"/> <result column="ssex" property="sex"/> <result column="sage" property="age"/> <result column="sscore" property="credit"/> <result column="smoney" property="money"/> <result column="saddress" property="address"/> <result column="senrol" property="enrol"/> </resultMap> <!--查詢所有學生 要使用上面的resultMap才能夠--> <select id="findAll" resultMap="studentMapper"> select * from student; </select> </mapper>
刪除以前在Mapper使用註解的SQL語句刪除,只留方法
springBoot集成Redis後,以上個案例的基礎上作個查詢學生緩存,若是第一次查詢則緩存到redis服務器裏,而後從redis讀取數據返回到客戶端
<!--導入redis啓動器--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
@RestController @RequestMapping("/student") public class StudentController { @Autowired private StudentService studentService; //注入redis模板對象 @Autowired private RedisTemplate redisTemplate; @RequestMapping("/findAll") public List<Student> findAll() { System.out.println("訪問成功"); //獲取類名 String className = studentService.getClass().getName(); //以類名+方法名的方式做爲key來查詢redis緩存數據 List<Student> studentList = (List<Student>) redisTemplate.boundValueOps(className + "findAll").get(); //redis沒有數據 查詢數據庫放入到redis if (studentList == null) { System.out.println("從數據庫查詢數據放入到redis"); //查詢數據庫 studentList = studentService.findAll(); //把查詢到的數據放入redis中 key爲類名加findAll redisTemplate.boundValueOps(className + "findAll").set(studentList); } else { System.out.println("從redis讀取數據緩存"); } //這裏經過json把對象寫到瀏覽器,要序列化對象 return studentList; } }
使用SpringBoot完成一個簡易的定時器,每5秒輸出一下當前的時間到控制檯;
首先在入口函數類上面加@EnableScheduling註解,表明開啓定時器
@Component public class TimerUtil { /** * @Scheduled 設置方法執行規則 就是定時任務設置 * cron: 設置一個String類型的cron表達式 這個屬性和下面6個不要混用 * fixedDelay 以一個固定的延遲時間,上個任務完成後多久執行下一個任務 * fixedDelayString 和上面同樣字符串形式傳值 * fixedRate 以一個固定的頻率運行,無論上一個任務執行時間 * fixedRateString 和上面同樣字符串形式傳值 * initialDelay 當項目初始化後多久觸發事務的執行 * initialDelayString 和上面同樣字符串形式傳值 */ //使用cron表達式 @Scheduled(initialDelay=10000,fixedDelay = 5000) public void myTask(){ System.out.println("當前時間:"+new Date()); } } //注:寫在入口函數類可掃描的範圍包下
<!--測試啓動start--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
//@RunWith(SpringRunner.class) 在老版的SpringBoot項目須要這個
//2.2.0.RELEASE之後,springboot測試類再也不須要@Runwith的註解
@SpringBootTest //註明爲SpringBoot測試類 class DemomybatissApplicationTests { //注入StudentService對象 @Autowired private StudentService studentService; @Test void contextLoads() { System.out.println(studentService.findAll()); } }
要在SpringBoot內部發送HTTP請求就得用到RestTemplate模板,它是Rest的HTTP客戶端模板工具類;對基於HTTP客戶端進行了封裝;還實現了對象與JSON的序列化與反序列化;不限定客戶端類型,目前經常使用的3種客戶端都支持:HttpClient、OKHttp、JDK原生URLConnection(默認方式)
@SpringBootApplication @EnableScheduling //開啓定時器註解 public class DemomybatissApplication { public static void main(String[] args) { SpringApplication.run(DemomybatissApplication.class, args); } //註冊RestTemplate對象放入IOC容器 @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } }
//@RunWith(SpringRunner.class) 在老版的SpringBoot項目須要這個 @SpringBootTest //註明爲SpringBoot測試類 class DemomybatissApplicationTests { //注入RestTemplate對象 @Autowired private RestTemplate restTemplate; @Test void contextLoads() { //String.class表明以字符串形式接收結果 String forObject = restTemplate.getForObject("http://baidu.com", String.class); System.out.println(forObject); //打印 //<html> //<meta http-equiv="refresh" content="0;url=http://www.baidu.com/"> //</html> } }
SpringBoot除了上面幾個集成外還集成 MongoDB、ElasticSearch、Memcached、郵件服務:普通郵件、模板郵件、驗證碼、帶Html的郵件、RabbitMQ消息中間件、Freemarker或者Thymeleaf等等
啓動方式有兩種,一種是打成jar直接執行,另外一種是打包成war包放到Tomcat服務下,啓動Tomcat
注:pom文件裏的<packaging>jar</packaging>必須爲jar,默認就是jar
/** * 第一步:使用IDEA工具把寫的代碼經過maven的package打包 * 第二步:找到打包後的target文件夾裏面,把xxx.jar包扔給測試 * 第三步:本身測試的話使用cmd執行下面命令,前提得檢查本身的pom.xml文件中是否有springboot的maven插件 * java -jar xxxx.jar * 補充:在運行的時候傳遞參數 經過main函數的args接收 * java -jar xxxx.jar --server.port=8888 * 補充:在運行的時候配置jvm參數,使佔用更少的內存 * java -Xmx80m -Xms20m -jar xxxx.jar */
注:pom文件裏的<packaging>war</packaging>必須爲jar,默認就是war
建立一個類如:ServletInitializer.java,繼承 SpringBootServletInitializer ,覆蓋 configure(), 把啓動類 Application 註冊進去。外部 Web 應用服務器構建 Web Application Context 的時候, 會把啓動類添加進去。 //以下代碼建立的類 除了類名和註冊的啓動類不同,其它是固定寫法 //WEB-INF/web.xml public class ServletInitializer extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { //DemoApplication是本身當前項目的主函數 return builder.sources(DemoApplication.class); } }
咱們在以前每次寫完代碼以後都要從新部署運行,這樣特別浪費時間,其實SpringBoot是支持熱部署的,可是咱們得有相對應的參數配置,導入座標
檢查當前的pom.xml必須有此配置才能夠,而後正常啓動運行便可
<!--工具 用於設置熱部署,optional必須爲true--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency>
當咱們的代碼寫文運行後,後期更改了代碼無需重寫部署,只須要按CTRL+F9(Build Project),這是快速構建項目,或點擊有上角的錘子;
若是還以爲麻煩,那就設置,一旦更改代碼,IDEA失去焦點就自動構建代碼,咱們要設置一下IDEA配置
咱們在開發Spring Boot應用時,一般同一套程序會被安裝到不一樣環境,好比:開發dev、測試test、生產pro等。其中數據庫地址、服務器端口等等配置都不一樣,若是每次打包時,都要修改配置文件,那麼很是麻煩。profile功能就是來進行動態配置切換的。
(1):單文件的多環境配置
# 在只有application.yml一個文件下配置多個配置環境就須要使用 " --- " 分隔界限 # 爲了規範 Dev爲開發 Test爲測試 Pro爲生產 # 配置完之後在這裏選擇要使用的配置環境 spring: profiles: # 開啓哪一個環境下的配置文件 active: oo # 引用包含哪一個配置文件 include: global # 開發環境配置 Dev --- server.port: 8881 # 設置當前的配置界限爲 dev開發環境 spring.profiles: dev # 測試環境配置 Test --- server.port: 8882 spring.profiles: test # 生產上線環境配置 Pro --- server.port: 80 spring.profiles: pro # 全局的配置供include包含使用 --- server.servlet.context-path: /littleBird spring.profiles: global
(2):多文件的多環境配置
⭐:application.yml 主配置文件(必須有) # 爲了規範 Dev爲開發 Test爲測試 Pro爲生產 # 配置完之後在這裏選擇要使用的配置環境 spring: profiles: # 開啓哪一個環境下的配置文件 active: dev # 引入包含共有配置 include: common ⭐:application-dev.yml/properties 開發環境配置 # 開發環境 server.port: 8881 ⭐:application-test.yml/properties 測試環境配置 # 測試環境 server.port: 8882 ⭐:application-pro.yml/properties 生產環境配置 # 上線環境 server.port: 80 ⭐:application-common.yml/properties 公共環境配置 # 公共配置 供其包含導入 server.servlet.context-path: /littleBird
(3):profile激活方式
在上面我介紹了使用配置文件來指定配置環境:spring.profiles.active=xx;但是這個是有侷限性的,除了這種方式激活還要另外2種
配置文件: 再配置文件中配置:spring.profiles.active=dev 虛擬機參數:在VM options 指定:-Dspring.profiles.active=dev 命令行參數:java –jar xxx.jar --spring.profiles.active=dev
優先級:命令行參數 > 虛擬機參數 > 配置文件
不論配置文件中的屬性值是短橫線、駝峯式仍是下換線分隔配置方式,在注入配置時均可以經過短橫線方式取出值;使用範圍:properties文件、YAML文件、系統屬性
⭐命名各類方式的名稱 application.yml文件下定義方式 # 短橫線分隔 parameter1: spring-boot: student-name: zhangsan # 駝峯式 parameter2: springBoot: studentName: lisi # 下劃線分隔 parameter3: spring_boot: student_name: wangwu ⭐命名各類方式的名稱 application.properties文件下定義方式 # 短橫線分隔 parameter1.spring-boot.student-name=zhangsan # 駝峯式 parameter2.springBoot.studentName=lisi # 下劃線分隔 parameter3.spring_boot.student_name: wangwu ⭐取出方式:使用短橫線分隔能夠取出上面的任意一直格式 注:在@Value獲取上面的3種方式命名的配置只能使用短橫線分隔通配 不然配置文件寫啥名,獲取就寫啥名,一一對應 @Value(value="${parameter1.spring-boot.student-name}") @Value(value="${parameter2.spring-boot.student-name}") @Value(value="${parameter3.spring-boot.student-name}")
外部加載順序就是說在程序運行時加載外部的配置信息的順序,如咱們經常使用的命令行下指定額外信息 java -jar xxx.jar --server.port=8888
# 這個是2.1.11版本的springboot以前的信息,中文的看的清楚,以具體版本爲準 1:開啓 DevTools 時, ~/.spring-boot-devtools.properties 2:測試類上的 @TestPropertySource 註解 3:@SpringBootTest#properties 屬性 4:==命令?參數(--server.port=9000 )== 5:SPRING_APPLICATION_JSON 中的屬性 6:ServletConfig 初始化參數 7:ServletContext 初始化參數 8:java:comp/env 中的 JNDI 屬性 9:System.getProperties() 10:操做系統環境變量 11:random.* 涉及到的 RandomValuePropertySource 12:jar 包外部的 application-{profile}.properties 或 .yml 13:jar 包內部的 application-{profile}.properties 或 .yml 14:jar 包外部的 application.properties 或 .yml 15:jar 包內部的 application.properties 或 .yml 16:@Configuration 類上的 @PropertySource 17:SpringApplication.setDefaultProperties() 設置的默認屬性
咱們知道配置文件只能以application.yml/properties來定義,可是名稱不同是能夠指定具體文件名,也能夠把配置文件放入其它位置並指定都是能夠的;指定的方式我以cmd下指定參數 java -jar xxx.jar --xxx -xxx 方式指定,或在IDEA裏面指定-xxx參數
# 自定義配置文件名稱 --spring.config.name=myApplication # 指定配置文件存儲位置 或 指定配置文件存儲位置及配置文件名稱
--spring.config.location=classpath:/myconfig/myApplication.yml
注:多個配置參數以空格隔開 --xxx -xxx
咱們知道JavaEE包括13門規範,其中Servlet規範包括三個技術點:Servlet、Listener、Filter;而本章介紹的是監聽器,監聽器就是監聽某個對象的狀態變化;SpringBoot中的監聽器有不少種:以下
①:CommandLineRunner 應用程序啓動完成後
②:ApplicationRunner 應用程序啓動完成後
③:ApplicationContextInitializer 程序運行初始化前
④:SpringApplicationRunListener 多功能監聽器
@Component //實現CommandLineRunner接口的監聽器必需要加入IOC容器 public class MyCommandLineRunner implements CommandLineRunner { //注 參數args是主函數入口的args傳來的 @Override public void run(String... args) throws Exception { System.out.println("應用程序啓動完成後 打印:CommandLineRunner"); } }
@Component //實現ApplicationRunner接口的監聽器必需要加入IOC容器 public class MyApplicationRunner implements ApplicationRunner { //注 參數args是主函數入口的args傳來的 @Override public void run(ApplicationArguments args) throws Exception { System.out.println("應用程序啓動完成後 打印:ApplicationRunner"); } }
public class MyApplicationContextInitializer implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext applicationContext) { System.out.println("程序運行初始化前 打印:ApplicationContextInitializer"); } }
public class MySpringApplicationRunListener implements SpringApplicationRunListener { //注意:此構造方法必需要寫 不寫就給你報個錯誤 public MySpringApplicationRunListener(SpringApplication application, String[] args) {} @Override public void starting(ConfigurableBootstrapContext bootstrapContext) { System.out.println("應用程序開始啓動==>starting"); } @Override public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) { System.out.println("環境準備完成==>environmentPrepared"); } @Override public void contextPrepared(ConfigurableApplicationContext context) { System.out.println("Spring容器準備完成==>contextPrepared"); } @Override public void contextLoaded(ConfigurableApplicationContext context) { System.out.println("Spring容器加載完成==>contextLoaded"); } @Override public void started(ConfigurableApplicationContext context) { System.out.println("應用程序啓動完成==>started"); } //注:running成功與failed異常只會存在一個 @Override public void running(ConfigurableApplicationContext context) { System.out.println("應用程序開始運行==>running"); } @Override public void failed(ConfigurableApplicationContext context, Throwable exception) { System.out.println("應用程序運行時拋出異常==>failed"); } }
# 說明 在resources目錄下建立META-INF文件夾 並在裏面建立一個spring.factories # 主要目的是解耦:將監聽器的配置權交給第三方廠商、插件開發者 # 框架提供接口,實現類由你本身來寫,釋放原生API能力,增長可定製性 # META-INF/spring.factories文件中配置接口的實現類名稱 # 配置ApplicationContextInitializer監聽器的配置 # 左邊監聽器的全路徑名稱=右邊實現此監聽器的全路徑名 org.springframework.context.ApplicationContextInitializer=cn.xw.lintener.MyApplicationContextInitializer # 配置SpringApplicationRunListener監聽器的配置 # 左邊監聽器的全路徑名稱=右邊實現此監聽器的全路徑名 org.springframework.boot.SpringApplicationRunListener=cn.xw.lintener.MySpringApplicationRunListener
咱們在導入spring-boot-starter-web啓動器無需其它配置就能夠之間用,還有咱們導入spring-boot-starter-data-redis啓動器後能夠直接使用@Autowired直接注入RedisTemplate對象,很奇怪吧,這就是SpringBoot自動配置特性,在下幾節我慢慢引入
當咱們須要導入某個類到spring容器中去,但spring剛好沒法掃描到這個類,而咱們又沒法修改這個類(jar包形式)。咱們就能夠經過@import(xxx.class)是將這個類導入到spring容器中
(1):直接導入
//配置類 springConfig @Configuration @Import(value={DateConfig.class}) //直接導入 public class SpringConfig { } //普通類,裏面有個@Bean注入方法 DateConfig //被任何一個配置類引用,當前本身類也變爲子配置類 public class DateConfig { //建立時間對象放入容器 @Bean public Date createDate() { return new Date(); } }
(2):經過配置類導入
@Configuration public class SpringConfig { //建立時間對象放入容器 @Bean public Date createDate() { return new Date(); } } @SpringBootApplication @Import(value={SpringConfig.class}) //導入配置類 public class LintenerDemoApplication { public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(LintenerDemoApplication.class, args); //打印時間對象 System.out.println(run.getBean(Date.class)); } }
(3):經過ImportSelector接口實現類導入 高級方式
//普通類 裏面有個@Bean注入對象 public class DateConfig { //建立時間對象放入容器 @Bean public Date createDate() { return new Date(); } } //建立一個類實現ImportSelector public class MyImportSelector implements ImportSelector { //這個方法是返回配置類的全類名,導入多少都行,最後經過@Import導入 @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { //返回一個數組 return new String[]{"cn.xw.config.DateConfig"}; } } @SpringBootApplication @Import(value={MyImportSelector.class}) //導入配置類 public class LintenerDemoApplication { public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(LintenerDemoApplication.class, args); //打印時間對象 System.out.println(run.getBean(Date.class)); } }
相對這個註解你們確定不陌生,只要是Spring註解配置類都有這玩意;其實只要添加@Configuration註解的類裏面能夠衍生出各類條件註解供咱們使用,前提只能在註解類下使用,它就是@Conditional條件註解,這個條件註解又衍生出各類詳細的條件註解
注:@EnableAutoConfiguration 其本質是 @Import 和 @Configuration的組合
一:class類條件 @ConditionalOnClass == 存在指定類條件 @ConditionalOnMissingClass == 不存在指定類條件 二:屬性條件 @ConditionalOnProperty == 屬性條件,還能夠爲屬性設置默認值 三:Bean條件 @ConditionalOnBean == 存在Bean條件 @ConditionalOnMissingBean == 不存在Bean條件 @ConditionalOnSingleCondidate == 只有一個Bean條件 四:資源條件 @ConditionalResource == 資源條件 五:Web應用條件 @ConditionalOnWebApplication == web應用程序條件 @ConditionalOnNotWebApplication == 不是web應用程序條件 六:其餘條件 @ConditionalOneExpression == EL表達式條件 @ConditionalOnJava == 在特定的Java版本條件
@Configuration還有一些加載順序的方式
1:@AutoConfigureBefore==在那些自動配置以前執行 2:@AutoConfigureAfter==在那些自動配置以後執行 3:@AutoConfigureOrder==自動配置順序
(1):@ConditionalOnClass 與 @ConditionalOnProperty 介紹
@ConditionalOnClass註解屬性介紹 Class<?>[] value():以類的class形式的數組 String[] name():以類的全路徑名的字符串數組 @ConditionalOnProperty註解屬性介紹 value 和 name:數組,獲取對應property名稱的值,它們只能存在其中一個 prefix:配置屬性名稱的前綴,好比spring.http.encoding havingValue:可與name組合使用,比較獲取到的屬性值與havingValue給定的值是否相同,相同才加載配置 matchIfMissing:缺乏該配置屬性時是否能夠加載。若是爲true,沒有該配置屬性時也會正常加載;反之則不會生效
//學生類 public class Student { private String name; private String identity; //省略了get/set, } //老師類 public class Teacher { private String name; private String identity; //省略了get/set, } //需求,當建立Teacher加入容器時得判斷當前是否存在Student這個類 @Configuration @ConditionalOnClass(name = "cn.xw.pojo.Student") public class SpringConfig { //能夠經過spring.myconfig.enable=true開啓 或者false 關閉容器註冊 @Bean(value = "teacher") @ConditionalOnProperty(prefix = "spring.myconfig", name = "enable", havingValue ="true", matchIfMissing = true) public Teacher createTeacher() { Teacher teacher = new Teacher(); teacher.setName("張老師"); teacher.setIdentity("老師"); return teacher; } } @SpringBootApplication //導入配置類 @Import(value={SpringConfig.class}) public class LintenerDemoApplication { public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(LintenerDemoApplication.class, args); //打印時間對象 System.out.println(run.getBean(Teacher.class).getName()); } } //application.properties # 關閉容器註冊 spring.myconfig.enable=false
//註解類 @Configuration(proxyBeanMethods = false) //條件註解 確保存在RedisOperations類 @ConditionalOnClass(RedisOperations.class) //@Import 和 @ConfigurationProperties結合 RedisProperties類就是咱們配置額外變量的spring.redis @EnableConfigurationProperties(RedisProperties.class) //導入配置類 @Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class }) public class RedisAutoConfiguration { @Bean //判斷不存在redisTemplate的Bean條件 @ConditionalOnMissingBean(name = "redisTemplate") //判斷只有一個RedisConnectionFactory的Bean條件 @ConditionalOnSingleCandidate(RedisConnectionFactory.class) public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<Object, Object> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory); return template; } //下面差很少 @Bean @ConditionalOnMissingBean @ConditionalOnSingleCandidate(RedisConnectionFactory.class) public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) { StringRedisTemplate template = new StringRedisTemplate(); template.setConnectionFactory(redisConnectionFactory); return template; } }
咱們日常導入是第三方mybatis-spring-boot-starter啓動器都是由第三方提供給,特色就是以mybatis開頭,那下面咱們自定義starter也得是自定義名稱開頭,咱們要自定義auto-Configuraction並使用必備的四個角色:功能主體框架、自動配置模塊、starter模塊、開發者引用
1:定製自動配置必要內容 autoconfiguration模塊,包含自動配置代碼。自定義 *-spring-boot-autoconfigure。 starter模塊。自定義 *-spring-boot-starter 2:自動配置命名方式 官方的Starters spring-boot-starter-* 如:spring-boot-starter-web 非官方的starters *-spring-boot-starter 如:mybatis-spring-boot-starter 3:SpringBoot起步依賴,Starter Dependencies
接下來我要建立一個第三方模塊,功能主體模塊是一個圖形打印模塊,根據配置文件的不一樣打印出不一樣的圖案,還要就是一個自動配置模塊和starter模塊咯,最後由我來在普通的springboot應用中調用這個自定義的自動配置
(1):功能主體模塊
⭐主體功能模塊maven座標 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.tx</groupId> <artifactId>graphic-printing</artifactId> <version>1.0-SNAPSHOT</version> <!--設置maven使用什麼版本的jdk解析編譯--> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> </project> ⭐主體功能模塊具體類方法 //圖形打印對象 public class GraphicPrintingUtil { private Integer width = 4; private Integer height = 3; //別忘了添加get/set方法,後面會參數注入 //打印圖形 方法 public void graphicPrinting() { System.out.println(">圖形開始打印<"); for (int i = 1; i <= height; i++) { for (int j = 1; j <= width; j++) { System.out.print(" * "); } System.out.println(); } } }
(2):自動配置模塊
⭐自動配置模塊maven座標 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!--導入Springboot父座標--> <parent> <artifactId>spring-boot-starter-parent</artifactId> <groupId>org.springframework.boot</groupId> <version>2.4.1</version> </parent> <!--當前本項目的一些信息--> <groupId>cn.tx</groupId> <artifactId>graphic-spring-boot-autoconfigure</artifactId> <version>1.0-SNAPSHOT</version> <!--座標--> <dependencies> <!--導入SpringBoot的自動配置座標 由於代碼中要寫配置註解--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> </dependency> <!--導入咱們以前建立的主體模塊graphic-printing--> <dependency> <groupId>cn.tx</groupId> <artifactId>graphic-printing</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project> ⭐自動配置模塊具體類方法 ## GraphicConfiguration類 @Configuration //註解類 @Import(value = {GraphicProperties.class}) //導入配置類 @ConditionalOnClass(GraphicPrintingUtil.class)//判斷當前項目是否存在GraphicPrintingUtil類 public class GraphicConfiguration { @Bean @ConditionalOnProperty(prefix = "graphic.printing", name = "enable", havingValue = "true", matchIfMissing = true) //@ConfigurationProperties(prefix = "graphic.config") 可使用此註解直接注入 注入時值無關緊要 public GraphicPrintingUtil createGraphicPrintingUtil(GraphicProperties g) { //建立圖形打印對象,主體模塊上的對象 GraphicPrintingUtil printingUtil = new GraphicPrintingUtil(); //設置寬高 printingUtil.setHeight(g.getHeight()); printingUtil.setWidth(g.getWidth()); return printingUtil; } } ## GraphicProperties 配置類 //這裏報紅無論他,後面使用者導入<artifactId>spring-boot-configuration-processor</artifactId> @ConfigurationProperties(prefix = "graphic.config") public class GraphicProperties { private Integer width; private Integer height; //別忘了寫get/set }
# 註冊自定義自動配置
# 前面是固定的,後面是自定義配置類
org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.tx.config.GraphicConfiguration
(3):stater模塊
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!--本身項目座標--> <groupId>cn.tx</groupId> <artifactId>graphic-spring-boot-starter</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!--主體功能模塊--> <dependency> <groupId>cn.tx</groupId> <artifactId>graphic-printing</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!--自動配置類autoconfigure--> <dependency> <groupId>cn.tx</groupId> <artifactId>graphic-spring-boot-autoconfigure</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project>
注:此模塊啥都不用,只要pom.xml文件便可
(3):開發者引用
注:此模塊和正常SpringBoot同樣,可使用腳手架構建 ⭐使用者maven座標 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!--springboot父座標--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.1</version> <relativePath/> </parent> <!--本項目的座標信息--> <groupId>cn.xw</groupId> <artifactId>test001</artifactId> <version>0.0.1-SNAPSHOT</version> <name>test001</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!--導入咱們自定義的stater啓動器--> <dependency> <groupId>cn.tx</groupId> <artifactId>graphic-spring-boot-starter</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!--必定要導入,是爲了注入配置文件裏面的數值--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> </dependencies> <!--maven插件--> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> ⭐使用者具體類方法 @SpringBootApplication public class Test001Application { public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(Test001Application.class, args); //ConfigurableApplicationContext是ClassPathXmlApplicationContext子類 run.getBean(GraphicPrintingUtil.class).graphicPrinting(); } } ⭐配置文件application.properties graphic.printing.enable=true graphic.config.width=10 graphic.config.height=15
SpringBoot的web環境中默認使用tomcat做爲內置服務器,其實還提供了另外2種內置服務器供咱們選擇,咱們能夠很方便的進行切換。
1:Tomcat:這個是使用最普遍但性能不太好的web應用服務器 默認
2:Jetty:Jetty 是一個開源的servlet容器,它爲基於Java的web容器,例如JSP和servlet提供運行環境。
3:Undertow: 是紅帽公司開發的一款基於 NIO 的高性能 Web 嵌入式服務器
Tomcat方式:Tomcat started on port(s): 8080 (http) with context path ''
Jetty方式:Jetty started on port(s) 8080 (http/1.1) with context path '/'
Undertow方式:Undertow started on port(s) 8080 (http)
<!--導入web的starter啓動器--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!--必定要排除tomcat的starter 由於默認就是tomcat--> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <!--導入jetty容器依賴--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jetty</artifactId> </dependency>
<!--導入web的starter啓動器--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!--必定要排除tomcat的starter 由於默認就是tomcat--> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <!--導入undertow容器依賴--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </dependency>
SpringBoot自帶監控功能Actuator,能夠幫助實現對程序內部運行狀況監控,好比監控情況、Bean加載狀況、配置屬性、日誌信息等
其實導入健康服務特別簡單,任何一個SpringBoot只須要加入一個監控啓動器則可開啓監控服務,而後項目正常運行便可
<!--監控服務Actuator啓動器-->
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
保存SpringBoot導入監控座標後啓動程序,在程序運行的狀況下訪問 http://localhost:8080/actuator 則可監控程序
補充:默認只能夠監控這幾項,其實能夠監測不少模塊
路徑 描述 默認開啓
/beans 顯示容器的所有的Bean,以及它們的關係 N
/env 獲取所有環境屬性 N
/env/{name} 根據名稱獲取特定的環境屬性值 N
/health 顯示健康檢查信息 Y
/info 顯示設置好的應用信息 Y
/mappings 顯示全部的@RequestMapping信息 N
/metrics 顯示應用的度量信息 N
/scheduledtasks 顯示任務調度信息 N
/httptrace 顯示Http Trace信息 N
/caches 顯示應用中的緩存 N
/conditions 顯示配置條件的匹配狀況 N
/configprops 顯示@ConfigurationProperties的信息 N
/loggers 顯示並更新日誌配置 N
/shutdown 關閉應用程序 N
/threaddump 執行ThreadDump N
/headdump 返回HeadDump文件,格式爲HPROF N
/prometheus 返回可供Prometheus抓取的信息 N
經常使用application.properties配置
# 暴露全部的監控點 management.endpoints.web.exposure.include=* # 定義Actuator訪問路徑 management.endpoints.web.base-path=/act # 開啓endpoint 關閉服務功能 訪問關閉路徑只能發送post請求才可關閉 management.endpoint.shutdown.enabled=true