14個(gè)SpringBoot優(yōu)化小妙招,寫(xiě)代碼像寫(xiě)詩(shī)
今天我們來(lái)分享一下平時(shí)用SpringBoot開(kāi)發(fā)時(shí)候的一些優(yōu)化小妙招,用好這些優(yōu)化小妙招讓我們開(kāi)發(fā)的系統(tǒng)架構(gòu)、系統(tǒng)代碼、開(kāi)發(fā)流程、測(cè)試流程、運(yùn)維監(jiān)控看起來(lái)就跟寫(xiě)詩(shī)一樣優(yōu)雅,讓我們每個(gè)人手頭負(fù)責(zé)的代碼和工程都要很漂亮~~~
這里的優(yōu)化小妙招很多不是說(shuō)直接對(duì)springboot來(lái)優(yōu)化,有些是對(duì)springboot自己的優(yōu)雅特性做一些總結(jié),幫助大家更加系統(tǒng)全面的了解springboot開(kāi)發(fā)的時(shí)候,如何做可以讓我們的代碼和系統(tǒng)更加的優(yōu)雅。
當(dāng)然,因?yàn)橐窒淼膬?yōu)化小妙招很多,我們更多的是給大家展示一下優(yōu)化的一些點(diǎn)和思路,具體的使用大家如果要落地,還得自己查閱官網(wǎng)資料!
1. 使用@SpringBootApplication注解簡(jiǎn)化配置
SpringBoot提倡“約定大于配置”,而@SpringBootApplication注解正是這一理念的體現(xiàn)。它集成了@Configuration、@EnableAutoConfiguration、@ComponentScan三個(gè)注解,讓你的主類配置瞬間簡(jiǎn)潔明了。
說(shuō)實(shí)話,一般來(lái)說(shuō)我們都是用springboot來(lái)開(kāi)發(fā)系統(tǒng)的時(shí)候,都是默認(rèn)都加@SpringBootApplication注解的,這個(gè)倒不能說(shuō)是優(yōu)化小妙招,更多的是給大家引入一下這個(gè)注解,我們可以學(xué)習(xí)一下springboot框架這種優(yōu)雅的設(shè)計(jì)理念。
也就是說(shuō),SpringBoot為了盡最大可能去簡(jiǎn)化一個(gè)web系統(tǒng)的啟動(dòng),設(shè)計(jì)了SpringApplication啟動(dòng)類一鍵啟動(dòng)一個(gè)web系統(tǒng),所有的web server、spring容器、bean管理、三方組件管理、擴(kuò)展組件管理,其實(shí)都是默認(rèn)行為去管控的,最大簡(jiǎn)化我們的系統(tǒng)開(kāi)發(fā),搭配上一些注解的使用,就從頭開(kāi)始就讓我們的系統(tǒng)非常優(yōu)雅!
@SpringBootApplication
public class MyApplication {
   public static void main(String[] args) {
       SpringApplication.run(MyApplication.class, args);
  }
}2. 利用配置文件簡(jiǎn)化代碼
SpringBoot支持多種格式的配置文件,如application.properties和application.yml。你可以將一些配置信息放在這里,減少硬編碼,讓代碼更加靈活。
這個(gè)說(shuō)實(shí)話一般人用springboot開(kāi)發(fā)系統(tǒng)也都是加配置文件的,畢竟配置信息不要寫(xiě)死在代碼里,把配置信息放外部配置文件,這樣才能優(yōu)雅,而且一般還可以搭配springboot的profile功能把不同環(huán)境的配置文件區(qū)分開(kāi)來(lái),部署的時(shí)候指定一個(gè)環(huán)境就可以了。
# application.yml
server:
port: 8080
my:
greeting: Hello, World!
@Value("${my.greeting}")
private String greeting;3. 使用Actuator監(jiān)控應(yīng)用
SpringBoot Actuator提供了很多內(nèi)置的端點(diǎn),讓你能夠監(jiān)控和管理應(yīng)用。比如/health端點(diǎn)可以告訴你應(yīng)用的健康狀態(tài),/metrics端點(diǎn)則提供了各種度量信息。
這個(gè)其實(shí)就是系統(tǒng)上線以后我們是需要對(duì)系統(tǒng)進(jìn)行監(jiān)控的,那一般小公司沒(méi)有大公司完善的基礎(chǔ)設(shè)施,如果我們要快速開(kāi)發(fā)和部署一個(gè)系統(tǒng)上線,其實(shí)可以直接用springboot自帶的監(jiān)控功能來(lái)對(duì)線上系統(tǒng)進(jìn)行基礎(chǔ)的監(jiān)控。
<!-- 在pom.xml中添加Actuator依賴 -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>4. 異步處理提升性能
SpringBoot支持異步處理,你可以使用@Async注解來(lái)異步執(zhí)行方法,提升應(yīng)用的性能和響應(yīng)速度,這個(gè)是一個(gè)好功能,如果執(zhí)行異步功能,一般我們都要自己開(kāi)線程去執(zhí)行異步任務(wù),但是用異步注解可以由框架啟動(dòng)一個(gè)內(nèi)嵌的異步任務(wù)執(zhí)行我們的代碼邏輯,這個(gè)相當(dāng)優(yōu)雅,有沒(méi)有?代碼是不是很漂亮!
@Service
public class AsyncService {
   @Async
   public void executeAsyncTask() {
       // 執(zhí)行異步任務(wù)
  }
}5. 利用緩存減少數(shù)據(jù)庫(kù)訪問(wèn)
SpringBoot支持多種緩存抽象,如ConcurrentMap、EhCache、Redis等。使用緩存可以減少對(duì)數(shù)據(jù)庫(kù)的訪問(wèn),提高應(yīng)用的性能。以前咱們用緩存的時(shí)候,那肯定是要自己封裝緩存組件的,完了在封裝好的緩存組件里基于開(kāi)源的緩存系統(tǒng)的客戶端來(lái)實(shí)現(xiàn)各類功能,對(duì)吧,然后再代碼里是不是我們還得自己動(dòng)手編寫(xiě)緩存讀寫(xiě)的代碼邏輯?
好,那現(xiàn)在我們可以用@CacheConfig、@Cacheable等注解直接讓框架去托管緩存的讀寫(xiě),自動(dòng)把數(shù)據(jù)庫(kù)查詢結(jié)果進(jìn)行緩存,以及下次查找的時(shí)候自動(dòng)讀取緩存,是不是感覺(jué)很方便?就省去了自己寫(xiě)緩存讀寫(xiě)代碼的過(guò)程了,又變得優(yōu)雅了有沒(méi)有~~~
@Service
@CacheConfig(cacheNames = "books")
public class BookService {
   @Cacheable
   public Book findBook(ISBN isbn) {
       // 模擬耗時(shí)操作
       return findBookFromDatabase(isbn);
  }
}6. 使用JPA簡(jiǎn)化數(shù)據(jù)庫(kù)操作
SpringBoot與Spring Data JPA結(jié)合,可以讓你用非常簡(jiǎn)潔的代碼完成復(fù)雜的數(shù)據(jù)庫(kù)操作。咱們平時(shí)要是封裝數(shù)據(jù)庫(kù)操作,是不是得自己動(dòng)手搞?那現(xiàn)在直接用Spring Data JPA來(lái)做數(shù)據(jù)庫(kù)操作的ORM,是不是感覺(jué)方便了很多?
以前我們得自己寫(xiě)sql語(yǔ)句,自己做數(shù)據(jù)的增刪改查,現(xiàn)在都是面向?qū)ο缶帉?xiě)數(shù)據(jù)庫(kù)操作邏輯,框架底層自動(dòng)托管生成sql語(yǔ)句去做數(shù)據(jù)庫(kù)的增刪改查,是不是很優(yōu)雅很方便?
public interface BookRepository extends JpaRepository<Book, Long> {
   List<Book> findByAuthor(String author);
}7. 優(yōu)化RESTful API設(shè)計(jì)
RESTful API的設(shè)計(jì)應(yīng)該簡(jiǎn)潔、直觀。使用SpringBoot,你可以很容易地創(chuàng)建RESTful API,并使用Swagger等工具進(jìn)行文檔生成和測(cè)試。這個(gè)功能實(shí)在是太常用了,沒(méi)用springboot的時(shí)候,其實(shí)咱們還得自己整合ssm框架,完了去用springmvc開(kāi)發(fā)web接口,現(xiàn)在用了springboot以后,內(nèi)嵌就幫我們搞定了spring和springmvc的框架整合這些事情,直接上手編寫(xiě)web接口,一鍵啟動(dòng)啟動(dòng)就可以對(duì)外提供http接口了,很方便有沒(méi)有~~~
@RestController
@RequestMapping("/books")
public class BookController {
   @GetMapping("/{id}")
   public ResponseEntity<Book> getBook(@PathVariable Long id) {
       // 獲取書(shū)籍并返回
  }
}8. 使用Spring Security保護(hù)應(yīng)用
SpringBoot與Spring Security的結(jié)合,可以讓你輕松地保護(hù)你的應(yīng)用。你可以配置用戶、角色、權(quán)限等,還可以使用OAuth2、JWT等高級(jí)特性。所謂的安全性保護(hù),說(shuō)白了就是我們寫(xiě)好的系統(tǒng)發(fā)布上線了,不能隨便誰(shuí)都可以來(lái)調(diào)用接口吧?不能隨便誰(shuí)來(lái)提交數(shù)據(jù)我們都允許修改系統(tǒng)數(shù)據(jù)庫(kù)里的數(shù)據(jù)吧?不能隨便誰(shuí)來(lái)查詢數(shù)據(jù)我們都開(kāi)放給他查詢吧?
那是不是得有一套安全防護(hù)機(jī)制?比如說(shuō)限制一下哪些http接口路徑要進(jìn)行防護(hù),我們防護(hù)的時(shí)候是怎么防護(hù),是不是說(shuō)要求請(qǐng)求方必須攜帶用戶token信息,然后是不是要對(duì)請(qǐng)求里帶的token信息進(jìn)行有效校驗(yàn)、權(quán)限校驗(yàn)?必須是我們?cè)试S的用戶攜帶了有效的校驗(yàn)信息,我們才可以允許他來(lái)請(qǐng)求系統(tǒng),是不是?
那所以這塊是不是可以跟spring security框架整合,直接把防護(hù)性功能給做了?
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
   @Override
   protected void configure(HttpSecurity http) throws Exception {
       http
          .authorizeRequests()
              .antMatchers("/", "/home").permitAll()
              .anyRequest().authenticated()
          .and()
          .formLogin()
          .and()
          .logout();
  }
}9. 利用Lombok簡(jiǎn)化模型類
Lombok是一個(gè)Java庫(kù),它可以自動(dòng)插入編輯器并構(gòu)建工具,簡(jiǎn)化Java模型類的編寫(xiě)。使用Lombok,你可以省去getter、setter、構(gòu)造器等方法的編寫(xiě)。這個(gè)lombok框架還是很方便的,因?yàn)槲覀冇辛怂?,就不用?dòng)手寫(xiě)一大堆的冗余方法了,讓我們的代碼更加簡(jiǎn)潔明了,domain領(lǐng)域?qū)ο罂梢詫W⒆约旱膶傩跃涂梢粤恕?/p>
@Data
public class Book {
   private Long id;
   private String title;
   private String author;
}10. 使用MapStruct處理對(duì)象映射
MapStruct是一個(gè)代碼生成器,它基于約定優(yōu)于配置的原則,可以在Java bean類型之間自動(dòng)實(shí)現(xiàn)映射。使用MapStruct,你可以避免手動(dòng)編寫(xiě)繁瑣的映射代碼。這個(gè)框架也是相當(dāng)?shù)挠杏?,我們?nèi)绻窃谝恍¬O、DO、DTO等對(duì)象之間進(jìn)行對(duì)象轉(zhuǎn)換,不用自己動(dòng)手封裝轉(zhuǎn)換邏輯了,直接用這個(gè)框架就可以實(shí)現(xiàn)對(duì)象轉(zhuǎn)換了,很優(yōu)雅有么有~~~
@Mapper
public interface BookMapper {
   BookMapper INSTANCE = Mappers.getMapper(BookMapper.class);
   BookDto toDto(Book entity);
   Book toEntity(BookDto dto);
}11. 使用Spring Boot Admin監(jiān)控多個(gè)應(yīng)用
Spring Boot Admin是一個(gè)開(kāi)源社區(qū)項(xiàng)目,用于管理和監(jiān)控基于Spring Boot的應(yīng)用。它可以顯示應(yīng)用的健康狀態(tài)、度量信息、環(huán)境屬性等。這個(gè)就跟我們上面說(shuō)的一樣,springboot快速開(kāi)發(fā)一個(gè)系統(tǒng)然后發(fā)布上線,咱們肯定要監(jiān)控,除了springboot內(nèi)嵌的監(jiān)控機(jī)制以外,還可以用springboot admin來(lái)進(jìn)行更加完善的監(jiān)控。
<!-- 在pom.xml中添加Spring Boot Admin Client依賴 -->
<dependency>
  <groupId>de.codecentric</groupId>
  <artifactId>spring-boot-admin-starter-client</artifactId>
</dependency>12. 使用Spring Cloud構(gòu)建微服務(wù)
SpringBoot與Spring Cloud的結(jié)合,可以讓你輕松地構(gòu)建微服務(wù)架構(gòu)的應(yīng)用。Spring Cloud提供了服務(wù)發(fā)現(xiàn)、配置中心、消息總線、負(fù)載均衡等微服務(wù)所需的組件。如果我們開(kāi)發(fā)的系統(tǒng)要拆分多個(gè)子系統(tǒng),或者是多個(gè)服務(wù),引入多人團(tuán)隊(duì)來(lái)協(xié)作開(kāi)發(fā),那肯定會(huì)引入微服務(wù)框架,要不然用springcloud原生技術(shù)棧,要不然用springcloud alibaba技術(shù)棧,這塊都是可以讓我們的系統(tǒng)變得更好,對(duì)不對(duì)?
@SpringBootApplication
@EnableDiscoveryClient
public class MicroserviceApplication {
   public static void main(String[] args) {
       SpringApplication.run(MicroserviceApplication.class, args);
  }
}13. 使用Spring Boot Test進(jìn)行集成測(cè)試
SpringBoot提供了強(qiáng)大的測(cè)試支持,你可以使用@SpringBootTest注解來(lái)進(jìn)行集成測(cè)試,還可以使用@MockBean、@SpyBean等注解來(lái)模擬依賴。這個(gè)其實(shí)很有用,因?yàn)槲覀兤綍r(shí)寫(xiě)好了代碼以后要進(jìn)行測(cè)試,一般就是單元測(cè)試、冒煙測(cè)試、集成測(cè)試、驗(yàn)收測(cè)試等,那其實(shí)用springboot test框架可以更加方便的幫助我們進(jìn)行各類代碼測(cè)試。
@SpringBootTest
public class BookServiceTests {
   @Autowired
   private BookService bookService;
   @Test
   public void testFindBook() {
       Book book = bookService.findBook("1234567890");
       assertNotNull(book);
       assertEquals("Spring Boot in Action", book.getTitle());
  }
}14. 使用Docker容器化部署
SpringBoot應(yīng)用可以很容易地容器化部署,使用Docker可以讓你的應(yīng)用在任何支持Docker的平臺(tái)上運(yùn)行。這個(gè)容器部署其實(shí)是現(xiàn)在非常流行的一種部署方式,說(shuō)白了就是我們的系統(tǒng)每次部署 一般都要設(shè)置各種參數(shù),可能還要攜帶各種配置,或者相關(guān)的一些其他東西,那其實(shí)如果每次部署多加一臺(tái)機(jī)器都要在機(jī)器里重新進(jìn)行環(huán)境配置等繁瑣操作,現(xiàn)在我們可以把這個(gè)工程和依賴的其他東西做成一個(gè)docker鏡像。
然后線上部署的時(shí)候再新的機(jī)器上直接安裝docker環(huán)境,基于我們的docker鏡像就可以一鍵部署系統(tǒng)了,是不是?相當(dāng)?shù)姆奖悖?/p>
# Dockerfile
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]總結(jié)
以上就是14個(gè)SpringBoot相關(guān)的優(yōu)化小妙招,希望它們能讓你的代碼不僅跑得快,還寫(xiě)得像首詩(shī)一樣美。SpringBoot的強(qiáng)大之處不僅僅在于它的簡(jiǎn)潔和易用,更在于它背后的一套完整的生態(tài)體系。掌握這些優(yōu)化技巧,你將能更加高效地開(kāi)發(fā)SpringBoot應(yīng)用,享受編碼的樂(lè)趣。















 
 
 










 
 
 
 