概述
1.基于Spring框架的“約定優先于配置(COC)”理念以及最佳實踐之路。
2.針對日常企業應用研發各種場景的Spring-boot-starter自動配置依賴模塊,且“開箱即用”(約定spring-boot-starter- 作為命名前綴,都位于org.springframenwork.boot包或者命名空間下)。
spring-boot-starter-jdbc
默認情況下,當我們沒有配置任何DataSource,SpringBoot會為我們自動配置一個DataSource,這種自動配置的方式一般適用于測試,開發還是自己配置一個DataSource的實例比較好。
如果我們的工程只依賴一個數據庫,那么,使用DataSource自動配置模塊提供的參數是最方便的:
spring.datasource.url=jdbc:mysql://{datasource host}:3306/{databaseName}
spring.datasource.username={database username}
spring.datasource.passwd={database passwd}
還會自動配置的有:JdbcTemplate DateSourceTransactionManager等,我們只要在使用的時候注入(@Autowired)就好了
此外,SpringBoot還支持的數據庫有spring-boot-data-jpa spring-boot-data-mongodb
spring-boot-starter-web
在當下項目運行mvn spring-boot:run就可以直接啟用一個嵌套了tomcat的web應用。
如果沒有提供任何服務的Cotroller,訪問任何路徑都會返回一個springBoot默認的錯誤頁面(Whitelabel error page)。
嵌入式Web容器層面的約定和定制
spring-boot-starter-web默認使用嵌套式的Tomcat作為Web容器對外提供HTTP服務,默認端口8080對外監聽和提供服務。
我們同樣可以使用spring-boot-starter-jetty或者spring-boot-starter-undertow作為Web容器。
想改變默認的配置端口,可以在application.properties中指定:
server.port = 9000(the port number you want)
類似的配置還有:
server.address
server.ssl.*
server.tomcat.*
如果上訴仍然沒有辦法滿足要求,springBoot支持對嵌入式的Web容器實例進行定制,可以通過向IoC容器中注冊一個EmbeddedServletContainerCustomizer類型的組件來對嵌入式的Web容器進行定制
public class UnveilSpringEmbeddedTomcatCustomizer implements EmbeddedServletContainer{public void customize(ConfigurableEmbeddedServletContainer container){container.setPort(9999);container.setContextPath("C\\hello");...}}
spring-boot-starter-test
進行springboot單元測試
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserControllerTest {@Autowiredprivate WebApplicationContext wac;private MockMvc mockMvc;@Beforepublic void setup() {mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();}@Testpublic void whenQuerySuccess() throws Exception {String result = mockMvc.perform(get("/user").param("username", "jojo").param("age", "18").param("ageTo", "60").param("xxx", "yyy")// .param("size", "15") //MockMvcRequestBuilders// .param("page", "3")// .param("sort", "age,desc").contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(status().isOk()).andExpect(jsonPath("$.length()").value(3)) //MockMvcResultMatchers.andReturn().getResponse().getContentAsString();System.out.println(result);}
spring-boot-devtools
當配置了 devtools 后,我們在classpath修改任何文件項目都將會自動重啟。
(1)某些資源在更改時不一定需要觸發重新啟動。例如, Thymeleaf 模板可以就地進行編輯。默認情況下更改資源路徑包括了:/META-INF/maven, /META-INF/resources ,/resources ,/static ,/public 或者 /templates 不會觸發重新啟動, 但會觸發實時重新加載。
如果逆向排除這些路徑,可以使用如下配置:
spring.devtools.restart.exclude=static/,public/
(2)如果要保留這些默認值并添加其他排除項, 請使用 spring.devtools.restart.additional-exclude 屬性代替。
(3)通過 System.setProperty(“spring.devtools.restart.enabled”, “false”); 方法,可以在SpringApplication.run()方法運行天使用關閉 devtools。
(4)當我們再次啟動 App.java 的時候,使用的加載器就變為了 restartedMain 了,說明熱部署已經成功。
注意點:devtools 由于是雙類加載機制,再結合了通用Mapper后可能會出現 java.lang.ClassCastException 異常(例如:說class x.x.A cannot be cast to x.x.A。)。
解決方案就如下:
在 src/main/resources 中創建 META-INF 目錄,在此目錄下添加 spring-devtools.properties 配置,內容如下:
restart.include.mapper=/mapper-[\w-\.]+jar
restart.include.pagehelper=/pagehelper-[\w-\.]+jar
spring-boot-starter-aop
AOP:Aspect Oriented Programming,面向切面編程
spring-boot-starter-aop主要由2部分組成:
1.位于spring-boot-autoconfigure的org.sringframework.boot.autoconfigure.aop.AopAutoConfiguration提供的@Configuration配置類和相應的配置項,即下面的2個配置項:
spring.aop.auto=true
spring.aop.proxy-target-class=false
2.spring-boot-starter-aop模塊提供了針對spring-aop aspectjrt 和aspectjweaver的依賴
spring-boot-starter-security
應用安全
spring-boot-starter-security 主要面向的是Web應用開發,配合spring-boot-starter-web
spring-boot-starter-security 默認會提供一個基于HTTP Basic認證的安全防護策略,默認用戶為user,訪問密碼則在當前web應用啟動的時候,打印到控制臺,要想定制,則在配置文件如下進行配置:
security.user.name={username}
security.user.password={passwd}
除此之外,spring-boot-starter-security還會默認啟動一些必要的Web安全防護,比如針對XSS CSRF等場針對Web應用的攻擊,同時,也會將一些常見的靜態資源路徑排除在安全防護之外。
AuthenticationManager AccessDecisionManager AbstractSecurityInterceptor被稱為Spring Security的基礎鐵三角,前2者負責制定規則, AbstractSecurityInterceptor負責執行。我們常見的Filter類就可以定制和擴展SpringSecurity的防護機制。
進一步定制spring-boot-starter-security
上訴使用SecurityProperties暴露的配置項,即以security.*對spring-boot-starter-security進行簡單的配置,還可以通過給出一個繼承了WebSecurityConfigurerAdapter的JavaConfig配置類對spring-boot-starter-security的行為進行更深級別的定制,例如:
- 使用其他的AuthenticationManager實例
- 對默認的HttpSecurity定義的資源訪問的規則重新定義
- 對默認提供的WebSecurity行為進行調整
- 一般配@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)進行標注。
mybatis-spring-boot-starter
MyBatis-Spring-Boot-Starter依賴將會提供如下
- 自動檢測現有的DataSource
- 將創建并注冊SqlSessionFactory的實例,該實例使用
- SqlSessionFactoryBean將該DataSource作為輸入進行傳遞
- 將創建并注冊從SqlSessionFactory中獲取的SqlSessionTemplate的實例。
- 自動掃描您的mappers,將它們鏈接到SqlSessionTemplate并將其注冊到Spring上下文,以便將它們注入到您的bean中。
使用了該Starter之后,只需要定義一個DataSource即可(application.properties或application.yml中可配置),它會自動創建使用該DataSource的SqlSessionFactoryBean以及SqlSessionTemplate。會自動掃描你的Mappers,連接到SqlSessionTemplate,并注冊到Spring上下文中。
pagehelper-spring-boot-starter
引入的jar包必須是要pagehelper-spring-boot-starter如果單獨引入pagehelper的話,分頁會不成功.
使用時PageHelper.startPage(pageNum, pageSize)一定要放在列表查詢上面,這樣在查詢時會查出相應的數據量且會查詢出總數,像圖中總數量有兩條,page里面查詢出來了是2,但list只查出了1條,因為我傳的分頁是pageNo=1,pageSize=1
PageHelper.startPage(pageNum, pageSize);
List<SystemUserPageVo> systemUserList = systemUserMapper.page(find);
PageInfo<SystemUserPageVo> page = new PageInfo<>(systemUserList);
打印的sql如下所示
Preparing: SELECT count(0) FROM (SELECT su.id, su.name, su.nick_name, su.email, su.phone, su.sex, su.fail_num, su.status, su.create_time, su.update_time, GROUP_CONCAT(sr.name) AS rolesName FROM SYSTEM_USER su, system_user_role sur, system_role sr WHERE su.id = sur.user_id AND sur.role_id = sr.id GROUP BY su.id) table_count
Parameters:
Total: 1
Preparing: SELECT su.id, su.name, su.nick_name, su.email, su.phone, su.sex, su.fail_num, su.status, su.create_time, su.update_time, group_concat(sr.name) as rolesName FROM SYSTEM_USER su, system_user_role sur, system_role sr WHERE su.id = sur.user_id AND sur.role_id = sr.id GROUP BY su.id LIMIT ?
Parameters: 1(Integer)
Total: 1
druid-spring-boot-starter
Druid是Java語言中最好的數據庫連接池。Druid能夠提供強大的監控和擴展功能。DruidDataSource支持的數據庫:
理論上說,支持所有有jdbc驅動的數據庫。最近發現Druid在springboot框架下有更加好用的Druid Spring Boot Starter,可以省去原本寫Druid的一些配置文件或者@Configuration來配置,直接將配置寫在application.yml里,看起來更簡單一些。
編寫application.yml,部分說明寫在注釋了:
spring:application:name: springboot-test-exam1datasource:# 使用阿里的Druid連接池type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driver# 填寫你數據庫的url、登錄名、密碼和數據庫名url: jdbc:mysql://localhost:3306/databaseName?useSSL=false&characterEncoding=utf8username: rootpassword: rootdruid:# 連接池的配置信息# 初始化大小,最小,最大initial-size: 5min-idle: 5maxActive: 20# 配置獲取連接等待超時的時間maxWait: 60000# 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒timeBetweenEvictionRunsMillis: 60000# 配置一個連接在池中最小生存的時間,單位是毫秒minEvictableIdleTimeMillis: 300000validationQuery: SELECT 1 FROM DUALtestWhileIdle: truetestOnBorrow: falsetestOnReturn: false# 打開PSCache,并且指定每個連接上PSCache的大小poolPreparedStatements: truemaxPoolPreparedStatementPerConnectionSize: 20# 配置監控統計攔截的filters,去掉后監控界面sql無法統計,'wall'用于防火墻filters: stat,wall,log4j# 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000# 配置DruidStatFilterweb-stat-filter:enabled: trueurl-pattern: "/*"exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"# 配置DruidStatViewServletstat-view-servlet:url-pattern: "/druid/*"# IP白名單(沒有配置或者為空,則允許所有訪問)allow: 127.0.0.1,192.168.163.1# IP黑名單 (存在共同時,deny優先于allow)deny: 192.168.1.73# 禁用HTML頁面上的“Reset All”功能reset-enable: false# 登錄名login-username: admin# 登錄密碼login-password: 123456
為了方便使用application.properties的讀者,使用下面的配置和上面相同
server.port=8080spring.application.name=springboot-test-exam1spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/databaseName?useSSL=false&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.druid.initial-size=5
spring.datasource.druid.min-idle=5
spring.datasource.druid.maxActive=20
spring.datasource.druid.maxWait=60000
spring.datasource.druid.timeBetweenEvictionRunsMillis=60000
spring.datasource.druid.minEvictableIdleTimeMillis=300000
spring.datasource.druid.validationQuery=SELECT 1 FROM DUAL
spring.datasource.druid.testWhileIdle=true
spring.datasource.druid.testOnBorrow=false
spring.datasource.druid.testOnReturn=false
spring.datasource.druid.poolPreparedStatements=true
spring.datasource.druid.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.druid.filters=stat,wall,log4j
spring.datasource.druid.connectionProperties=druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
spring.datasource.druid.web-stat-filter.enabled=true
spring.datasource.druid.web-stat-filter.url-pattern=/*
spring.datasource.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
spring.datasource.druid.stat-view-servlet.allow=127.0.0.1,192.168.163.1
spring.datasource.druid.stat-view-servlet.deny=192.168.1.73
spring.datasource.druid.stat-view-servlet.reset-enable=false
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=123456
mybatis-generator-core
SSM框架可以使用mybatis-generator-core-1.3.2.jar來自動生成代碼,以下是配置和使用的代碼。
generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"><generatorConfiguration><context id="testTables" targetRuntime="MyBatis3"><commentGenerator><!-- 是否去除自動生成的注釋 true:是 : false:否 --><property name="suppressAllComments" value="true" /></commentGenerator><!--數據庫連接的信息:驅動類、連接地址、用戶名、密碼 --><jdbcConnection driverClass="com.mysql.jdbc.Driver"connectionURL="jdbc:mysql://localhost:3306/crm" userId="root"password="1111"> </jdbcConnection> <!-- 數據庫連接配置 sqlserver--><!--<jdbcConnection driverClass="com.microsoft.sqlserver.jdbc.SQLServerDriver"connectionURL="jdbc:sqlserver://gsdy.eicp.net:8633;databasename=qkmls"userId="sa"password="sa@20170410" />--><!--<jdbcConnection driverClass="oracle.jdbc.OracleDriver"connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg" userId="yycg"password="yycg"></jdbcConnection> --><!-- 默認false,把JDBC DECIMAL 和 NUMERIC 類型解析為 Integer,為 true時把JDBC DECIMAL 和 NUMERIC 類型解析為java.math.BigDecimal --><javaTypeResolver><property name="forceBigDecimals" value="false" /></javaTypeResolver><!-- targetProject:生成PO類的位置 --><javaModelGenerator targetPackage="com.ma.core.po"targetProject=".\src"><!-- enableSubPackages:是否讓schema作為包的后綴 --><property name="enableSubPackages" value="false" /><!-- 從數據庫返回的值被清理前后的空格 --><property name="trimStrings" value="true" /></javaModelGenerator><!-- targetProject:mapper映射文件生成的位置 --><sqlMapGenerator targetPackage="com.ma.mapper" targetProject=".\src"><!-- enableSubPackages:是否讓schema作為包的后綴 --><property name="enableSubPackages" value="false" /></sqlMapGenerator><!-- targetPackage:mapper接口生成的位置 --><javaClientGenerator type="XMLMAPPER"targetPackage="com.ma.core.dao" targetProject=".\src"><!-- enableSubPackages:是否讓schema作為包的后綴 --><property name="enableSubPackages" value="false" /></javaClientGenerator><!-- 指定數據庫表 --><table tableName="customer" schema=""/><table tableName="sys_user" schema=""/><table tableName="base_dict" schema=""/><!-- <table schema="" tableName="T_Qk_Orders"></table><table schema="" tableName="T_Qk_Orderitem"></table><table schema="" tableName="T_Qk_Amount"></table> --><!--<table schema="" tableName="tb_content"></table><table schema="" tableName="tb_content_category"></table><table schema="" tableName="tb_item"></table><table schema="" tableName="tb_item_cat"></table><table schema="" tableName="tb_item_desc"></table><table schema="" tableName="tb_item_param"></table><table schema="" tableName="tb_item_param_item"></table><table schema="" tableName="tb_order"></table><table schema="" tableName="tb_order_item"></table><table schema="" tableName="tb_order_shipping"></table><table schema="" tableName="tb_user"></table> --></context>
</generatorConfiguration>
GeneratorSqlmap.java使用代碼
package com.ma.common.utils;import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.DefaultShellCallback;public class GeneratorSqlmap {public void generator() throws Exception{List<String> warnings = new ArrayList<String>();boolean overwrite = true;//指定 逆向工程配置文件File configFile = new File("resource/generatorConfig.xml");ConfigurationParser cp = new ConfigurationParser(warnings);Configuration config = cp.parseConfiguration(configFile);DefaultShellCallback callback = new DefaultShellCallback(overwrite);MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,callback, warnings);myBatisGenerator.generate(null);} public static void main(String[] args) throws Exception {try {GeneratorSqlmap generatorSqlmap = new GeneratorSqlmap();generatorSqlmap.generator();} catch (Exception e) {e.printStackTrace();}}}
把上面的配置文件和代碼,放到一個可以運行的項目下運行就可以了。根據自己的需求配置不同的數據源和生成代碼的位置。
commons-lang3
這個包中的很多工具類可以簡化我們的操作,在這里簡單的研究其中的幾個工具類的使用。
apache提供的眾多commons工具包,號稱Java第二API,而common里面lang3包更是被我們使用得最多的。因此本文主要詳細講解lang3包里面幾乎每個類的使用,希望以后大家使用此工具包,寫出優雅的代碼