@SpringBootApplication
這個註解其實我們常見但是又不怎麼主動使用。這個註解是spring boot項目的基石。會默認在啓動類上加上。其實我們可以把這個註解看成是多個註解的集合:
其中主要的三個註解是:
-
@SpringBootConfiguration:它的底層其實是@Configuration.允許在Spring上下文中註冊額外的bean或者導入其它配置類。
- @ComponentScan:掃描被@Component,@Repository,@Service,@Controller註解的bean,註解默認會掃描該類所在的包下的所有的類(這也是boot項目啓動類必須在最外層的原因)
- @EnableAutoConfiguration:啓動SpringBoot的自動配置機制。
Spring Bean相關
@Autowired
自動導入對象到類中,被注入進的類同樣要被spring容器管理。比如Service類注入到Controller類中。
@Component,@Repository,@Service,@Controller
我們一般使用@Autowired註解讓Spring容器幫我們自動裝配bean。要想要類標識成可用於@Autowired註解自動裝配的bean的類,可以採用以下註解實現:
- @Component:通用的註解,可標註任意類爲Spring組件。如果一個bean不知道屬於哪層,可以使用這個註解來標註。
- @Repository:對應持久層即Dao層,主要用於數據庫相關操作。
- @Service:對應服務層,主要涉及一些複雜的邏輯,需要用到Dao層。
- @Controller:對應Spring MVC控制層。主要用於接受用戶請求並調用Service層返回數據給前端頁面。
@RestController
@RestController註解是@Controller和@ResponseBody的合集。表示這是個控制器bean,並且將函數的返回值直接填入http響應體中。是REST風格的控制器。
單獨使用@Controller不加@ResponseBody的話,一般是用在要返回一個視圖的情況。如果加了@ResponseBody返回的是JSON或者XML形式的數據。
@Scope
這個是聲明Spring Bean的作用域,使用方法就是指定作用域。這個註解有四種常見的作用域:
- singleton:唯一bean實例。Spring中的bean默認都是單例的
- prototype:每次請求都會創建一個新的bean實例
- request:每一個HTTP請求都會產生一個新的bean,該bean僅在當前http的request中有效。
- session:每一個http session會產生一個新的bean。該bean僅在當前http session下有效。
下面的簡單的例子:
@Configuration
一般用來聲明配置類,可以使用註解@Component註解替代。不過使用@Configuration註解聲明配置類更加語義化。
處理常見的http請求類型
5中常見的請求類型(其實就前兩個常見,三四個也還行。第五個沒用過。 )
- GET:請求從服務器獲取特定資源。
- POST:在服務器上創建一個新的資源
- PUT:更新服務器上的資源
- DELETE:從服務器刪除特定的資源
- PATCH:更新服務器上的資源。
GET請求
@GetMapper("/xxx") 等價於
@RequestMapper(value= "/xxx",method=RequestMethod.GET)
POST請求
@PostMapping("/xxx") 等價於@RequestMapping(value="/xxx",method=RequestMethod.POST)
PUT請求
@PutMapping("/xxx/{userId}") 等價於@RequestMapping(value="/xxx/{userId}",method=RequestMethod.PUT)
DELETE請求
@DeleteMapping("/xxx/{userId}")等價於@RequestMapping(value="/xxx/{userId}",method=RequestMethod.DELETE)
PATCH請求
一般我們很少使用的這個請求,都是put不夠用了纔會使用。
@PatchMapping("/xx")等價於
@RequestMapping(value = "/xxx",method = RequestMethod.PATCH)
前後端傳值
@PathVariable 和@RequestParam
@PathVariable用於獲取路徑參數
@RequestParam用戶就獲取查詢參數
這兩者我們可以同時使用。如下例子:
@GetMapping("/test/{name}")
public String test(@PathVariable("name")String name,@RequestParam("id") String id){
return "id = "+ id +",name = " + name ;
}
@RequestBody
用於讀取Requst請求的body部分,並且Content-Type是application/json格式的參數。接收到數據之後會自動將數據綁定到java對象上去。系統會使用HttpMessageConyerter或者自定義的HttpMessageConyerter將請求的body中的json字符串轉換爲java對象。
需要注意一個請求方法裏只能有一個@RequestBody,但是可以有多個@RequestParam和@PathVariable.
讀取配置信息
很多時候我們需要將一些常用的配置信息比如阿里雲oss,發送短信,微信認證的相關配置信息等等放到配置文件中。下面我們來看一下spring爲我們提供了哪些方式從配置文件中讀取配置信息。
@Value
這個是比較常用的讀取配置信息註解,使用方法是@Value("${xxx}")
@ConfigurationProperties
通過@ConfigurationProperties讀取配置信息並且與bean綁定。如下demo:
@PropertySource
這個是讀取指定位置的配置文件,然後用@Value註解注入。
怎麼說呢,我是覺得這個挺雞肋的。也可能是我沒遇到適用的場景。比如說A,B兩個文件中都有url屬性。如果我們直接用@Value注入的話是要aplication.yml/properties文件。但是我們可以在類上指定要讀取的配置文件,然後用@Value注入。
全局處理Controller層異常
- @ControllerAdvice:註解定義全局異常處理類
- @ExceptionHandler:註解聲明異常處理方法
這個使用不難,但是挺墨跡的,我就不整理了,感興趣的自己百度吧。
JPA相關
創建表
@Entity聲明一個類對應一個數據庫實體。
@Table 設置表名
@Entity
@Data
@Table(name = "sys_user")
public class User{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Integer age;
}
創建主鍵
@Id :聲明一個字段爲主鍵。
@GeneratedValue 指定主鍵生成策略。
jpa中常見的有四種主鍵生產策略。默認是auto
public enum GenerationType {
/**
* 使用一個特定的數據庫表格來保存主鍵
* 持久化引擎通過關係數據庫的一張特定的表格來生成主鍵,
*/
TABLE,
/**
*在某些數據庫中,不支持主鍵自增長,比如Oracle、PostgreSQL其提供了一種叫做"序列(sequence)"的機制生成主鍵
*/
SEQUENCE,
/**
* 主鍵自增長
*/
IDENTITY,
/**
*把主鍵生成策略交給持久化引擎(persistence engine),
*持久化引擎會根據數據庫在以上三種主鍵生成 策略中選擇其中一種
*/
AUTO
}
設置字段類型
@Column 聲明字段。
可以設置數據庫的字段名。也可以設置非空,長度等。還可以添加默認值。比如下面兩個demo:
@Column(name = "user_name", nullable = false, length=32)
private String userName;
@Column(columnDefinition = "tinyint(1) default 1")
private Boolean enabled;
指定不持久化特定字段
@Transient :聲明不需要與數據庫映射的字段,在保存的時候不需要保存進數據庫 。
其實這個mybatis也有類似的功能。就是當實體和數據庫表有出入的時候可以用。
聲明大字段
@Lob:聲明某個字段爲大字段。
創建枚舉類型的字段
這個實用性還蠻高的。比如傳入的男性,女性.然後枚舉值定義男性是male,女性是female這種。就是使用比較麻煩,需要自己寫枚舉類。
public enum Gender {
MALE("男性"),
FEMALE("女性");
private String value;
Gender(String str){
value=str;
}
}
@Entity
@Data
@Table(name = "sys_user")
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@Enumerated(EnumType.STRING)
private Gender gender;
}
增加審計功能
這個功能其實就是自動給創建人,創建時間,修改人,修改時間賦值。實現如下:
只要繼承了AbstractAuditBase的類都會默認加上這四個字段。這裏的幾個註解都比較見名知意,我就不多解釋了。
@Data
@AllArgsConstructor
@NoArgsConstructor
@MappedSuperclass
@EntityListeners(value = AuditingEntityListener.class)
public abstract class AbstractAuditBase {
@CreatedDate
@Column(updatable = false)
@JsonIgnore
private Instant createdAt;
@LastModifiedDate
@JsonIgnore
private Instant updatedAt;
@CreatedBy
@Column(updatable = false)
@JsonIgnore
private String createdBy;
@LastModifiedBy
@JsonIgnore
private String updatedBy;
}
然後需要實現一個auditorAware的接口,用處就是爲了返回當前的操作人。
@Configuration
@EnableJpaAuditing
public class AuditSecurityConfiguration {
@Bean
AuditorAware<String> auditorAware() {
return request.getSession().getAttribute("username");
}
}
然後我們在啓動類上添加註解@EnableJpaAuditing,開啓 JPA 審計功能。
刪除/修改數據
@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
@Modifying
@Transactional(rollbackFor = Exception.class)
void deleteByUserName(String userName);
}
關聯關係
雖然jpa支持一對一,一對多,多對多等。但是實際上項目中不推薦這麼使用,所以我就不多介紹了。反正jpa是支持的,感興趣的自己去看官網。
事務@Transactional
關於spring事務,我之前有篇文章整理過,感興趣的可以自己去看看。https://www.jianshu.com/p/78ef931a4674
json數據處理
過濾json數據
@JsonIgnoreProperties 作用在類上用於過濾掉特定字段不返回或者不解析
//生成json時將userRoles屬性過濾
@JsonIgnoreProperties({"userRoles"})
public class User {
private String userName;
private String fullName;
private String password;
private List<UserRole> userRoles = new ArrayList<>();
}
@JsonIgnore作用於屬性上和@JsonIgnoreProperties是一樣的。
public class User {
private String userName;
private String fullName;
private String password;
//生成json時將userRoles屬性過濾
@JsonIgnore
private List<UserRole> userRoles = new ArrayList<>();
}
格式化json數據
@JsonFormat一般用來格式化 json 數據。
比如我們可以把日期用字符串接收
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone="GMT")
private Date date;
扁平化對象
其實所謂的扁平化我們可以理解成從子對象中取出來放在外層。
上面這段代碼執行結果是這樣的:
{
"userEntity": {
"id": null,
"name": "lsj",
"age": 12,
"level": 1,
"flag": true,
"email": "[email protected]"
}
}
而如果我們在屬性上添加註解:@JsonUnwrapped。
執行結果變成這樣:
{
"id": null,
"name": "lsj",
"age": 12,
"level": 1,
"flag": true,
"email": "[email protected]"
}
測試相關
@SpringBootTest(webEnvironment = RANDOM_PORT) 聲明是測試
@ActiveProfiles("test") 指定運行環境是test,用於讀取spring配置文件/
@Test 聲明一個方法爲測試方法
@Transactional被聲明的測試方法的數據會回滾,避免污染測試數據。
@WithMockUser Spring Security 提供的,用來模擬一個真實用戶,並且可以賦予權限。
本篇筆記就記到這裏,真正做的時候才發現spring註解之多真的很難整理清楚,從一開始的興致勃勃到後來無從下手。不過還算是有個心得:當你需要什麼功能的時候不妨先去百度找找,大部分spring 全家桶已經提供輪子了。哪怕spring不提供,也很大機率有現成的輪子。本篇筆記就記到這裏,如果稍微幫到你了記得點個喜歡點個關注,也祝大家工作順順利利!