前言
在使用spring的過程中,我們有沒有發(fā)現(xiàn)它的擴展能力很強呢?由于這個優(yōu)勢的存在,使得spring具有很強的包容性,所以很多第三方應用或者框架可以很容易的投入到spring的懷抱中。今天我們主要來學習Spring中很常用的11個擴展點,你用過幾個呢?
1. 類型轉換器
如果接口中接收參數(shù)的實體對象中,有一個字段類型為Date,但實際傳遞的參數(shù)是字符串類型:2022-12-15 10:20:15,該如何處理?
Spring提供了一個擴展點,類型轉換器Type Converter
,具體分為3類:
Converter
: 將類型 S 的對象轉換為類型 T 的對象ConverterFactory
: 將 S 類型對象轉換為 R 類型或其子類對象GenericConverter
:它支持多種源和目標類型的轉換,還提供了源和目標類型的上下文。此上下文允許您根據(jù)注釋或屬性信息執(zhí)行類型轉換。
還是不明白的話,我們舉個例子吧。
- 定義一個用戶對象
@Data
public class User {
private Long id;
private String name;
private Date registerDate;
}
- 實現(xiàn)
Converter
接口
public class DateConverter implements Converter
- 將新定義的類型轉換器注入到Spring容器中
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new DateConverter());
}
}
- 調(diào)用接口測試
@RequestMapping("/user")
@RestController
public class UserController {
@RequestMapping("/save")
public String save(@RequestBody User user) {
return "success";
}
}
請求接口時,前端傳入的日期字符串,會自動轉換成Date類型。
2. 獲取容器Bean
在我們?nèi)粘i_發(fā)中,經(jīng)常需要從Spring容器中獲取bean,但是你知道如何獲取Spring容器對象嗎?
2.1 BeanFactoryAware
@Service
public class PersonService implements BeanFactoryAware {
private BeanFactory beanFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
public void add() {
Person person = (Person) beanFactory.getBean("person");
}
}
實現(xiàn)BeanFactoryAware接口,然后重寫setBeanFactory方法,可以從方法中獲取spring容器對象。
2.2 ApplicationContextAware
@Service
public class PersonService2 implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public void add() {
Person person = (Person) applicationContext.getBean("person");
}
}
實現(xiàn)ApplicationContextAware
接口,然后重寫setApplicationContext
方法,也可以通過該方法獲取spring容器對象。
2.3 ApplicationListener
@Service
public class PersonService3 implements ApplicationListener<ContextRefreshedEvent> {
private ApplicationContext applicationContext;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
applicationContext = event.getApplicationContext();
}
public void add() {
Person person = (Person) applicationContext.getBean("person");
}
}
3. 全局異常處理
以往我們在開發(fā)界面的時候,如果出現(xiàn)異常,要給用戶更友好的提示,例如:
@RequestMapping("/test")
@RestController
public class TestController {
@GetMapping("/add")
public String add() {
int a = 10 / 0;
return "su";
}
}
如果不對請求添加接口結果做任何處理,會直接報錯:
用戶可以直接看到錯誤信息嗎?
這種交互給用戶帶來的體驗非常差。為了解決這個問題,我們通常在接口中捕獲異常:
@GetMapping("/add")
public String add() {
String result = "success";
try {
int a = 10 / 0;
} catch (Exception e) {
result = "error";
}
return result;
}
界面修改后,出現(xiàn)異常時會提示:“數(shù)據(jù)異常”,更加人性化。
看起來不錯,但是有一個問題。
如果只是一個接口還好,但是如果項目中有成百上千個接口,還得加異常捕獲代碼嗎?
答案是否定的,這就是全局異常處理派上用場的地方:RestControllerAdvice
。
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public String handleException(Exception e) {
if (e instanceof ArithmeticException) {
return "data error";
}
if (e instanceof Exception) {
return "service error";
}
retur null;
}
}
方法中處理異常只需要handleException
,在業(yè)務接口中就可以安心使用,不再需要捕獲異常(統(tǒng)一有人處理)。
4. 自定義攔截器
Spring MVC攔截器,它可以獲得HttpServletRequest
和HttpServletResponse
等web對象實例。
Spring MVC攔截器的頂層接口是HandlerInterceptor
,它包含三個方法:
preHandle
在目標方法執(zhí)行之前執(zhí)行- 執(zhí)行目標方法后執(zhí)行的
postHandle
afterCompletion
在請求完成時執(zhí)行
為了方便,我們一般繼承HandlerInterceptorAdapter
,它實現(xiàn)了HandlerInterceptor
。
如果有授權鑒權、日志、統(tǒng)計等場景,可以使用該攔截器,我們來演示下吧。
- 寫一個類繼承
HandlerInterceptorAdapter
:
public class AuthInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
String requestUrl = request.getRequestURI();
if (checkAuth(requestUrl)) {
return true;
}
return false;
}
private boolean checkAuth(String requestUrl) {
return true;
}
}
- 將攔截器注冊到spring容器中
@Configuration
public class WebAuthConfig extends WebMvcConfigurerAdapter {
@Bean
public AuthInterceptor getAuthInterceptor() {
return new AuthInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor());
}
}
- Spring MVC在請求接口時可以自動攔截接口,并通過攔截器驗證權限。
5. 導入配置
有時我們需要在某個配置類中引入其他的類,引入的類也加入到Spring容器中。這時候可以使用注解@Import
來完成這個功能。
如果你查看它的源代碼,你會發(fā)現(xiàn)導入的類支持三種不同的類型。
但是我覺得最好把普通類的配置類和@Configuration
注解分開解釋,所以列出了四種不同的類型:
-
轉換器
+關注
關注
27文章
8745瀏覽量
148056 -
框架
+關注
關注
0文章
403瀏覽量
17543 -
spring
+關注
關注
0文章
340瀏覽量
14390
發(fā)布評論請先 登錄
相關推薦
什么是java spring
Spring工作原理
啟動Spring Boot項目應用的三種方法
STM32時鐘系統(tǒng)最常用的知識
高手最常用的電腦五個組合鍵
Spring應用 1 springXML配置說明
Spring認證_什么是Spring GraphQL?
![<b class='flag-5'>Spring</b>認證_什么是<b class='flag-5'>Spring</b> GraphQL?](https://file.elecfans.com//web2/M00/0F/03/pYYBAGEQoZGAASYfAAG9KGVFbn4674.jpg)
最常用的11款Kubernetes工具
Spring中最常用的11個擴展點
剖析Spring中最常用的擴展點(上)
![剖析<b class='flag-5'>Spring</b>中<b class='flag-5'>最常用</b>的<b class='flag-5'>擴展</b><b class='flag-5'>點</b>(上)](https://file.elecfans.com/web2/M00/91/89/pYYBAGPskaeACHqYAAJpkEr10mM116.jpg)
剖析Spring中最常用的擴展點(中)
![剖析<b class='flag-5'>Spring</b>中<b class='flag-5'>最常用</b>的<b class='flag-5'>擴展</b><b class='flag-5'>點</b>(<b class='flag-5'>中</b>)](https://file.elecfans.com/web2/M00/91/06/poYBAGPskaeAN7p6AAEMAjYtrFo527.jpg)
評論