在咱們開發項目的時候各個項目之間總有一些可共用的代碼或者配置,若是咱們每新建一個項目就把代碼複製粘貼再修改就顯得很沒有必要。因而我就作了一個 poseidon-boot-starter
該項目是基於 spring-boot
的 starter 功能開發的,所以只適用於 spring-boot
項目。該項目集成了以下功能:前端
項目地址:github.com/muggle0/pos…java
下面介紹該組件如何在咱們的 spring-boot 項目中使用。git
首先咱們須要下載下來這個項目:github
git clone https://github.com/muggle0/poseidon-boot-starter.git複製代碼
而後安裝到咱們的本地倉庫或者私有云:web
cd poseidon-boot-starter
mvn install複製代碼
安裝完成以後在spring boot 項目中引入依賴:redis
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>複製代碼
而後進行一些基礎的配置:spring
poseidon.auto=true
poseidon.static-path=/**/*.*
poseidon.ignore-path=/**
logging.config=classpath:poseidon-logback.xml
log.dir=logs
logging.level.com.muggle=debug
spring.profiles.include=refresh
複製代碼
自動化配置默認是不開啓的,咱們須要使用 poseidon.auto=true
來啓用相關功能,當開啓自動化配置以後,咱們必需要實現兩個接口並注入到spring容器—— com.muggle.poseidon.store.SecurityStore
和 com.muggle.poseidon.service.TokenService
。poseidon.static-path
是 ant 匹配的靜態資源路徑,符合該規則的url不會被權限過濾器攔截,poseidon.ignore-path
是鑑權忽略規則,符合該規則的url不會參與鑑權,直接放行。logging.config=classpath:poseidon-logback.xml
則是採用 poseidon-boot-starter
中的logback配置策略(五彩斑斕的黑),若是採用該配置則必須指定 log.dir
日誌文件輸出路徑。logging.level.com.muggle=debug
是指定包名以debug的級別輸出,方便看一些日誌調試。spring.profiles.include=refresh
當指定這個 profile
的時候,會去獲取當前項目的全部url並交給 tokenService
去處理。還有其餘默認不開啓的功能,在源碼解讀中介紹。數據庫
前文咱們提到過,該項目是基於 springboot 的 starter 功能開發的,其原理就是一個 springboot 定製版的 spi 這裏不作太多介紹,這裏我主要介紹如何在項目中使用的。express
首先在 META-INF/spring.factories
,中指定了要注入的類有哪些:json
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.muggle.poseidon.auto.ExpansibilityConfig,\
com.muggle.poseidon.auto.SecurityAutoConfig,\
com.muggle.poseidon.handler.web.WebUrlHandler,\
com.muggle.poseidon.handler.web.WebResultHandler複製代碼
ExpansibilityConfig
是預留的配置類,實際未使用,SecurityAutoConfig
是整合 spring-security
相關的配置。WebUrlHandler
是處理一些特殊的url的。WebResultHandler
是統一異常處理配置。這幾個類都經過 @ConditionalOnProperty(prefix = "poseidon", name = "auto", havingValue = "true", matchIfMissing = false)
來控制是否自動配置。配置類具體的源碼細節這裏就不介紹了。下面對各個功能的源碼進行解讀。
項目集成了security,並重寫了處理器和鑑權相關的類,改形成了純返回json,並從請求頭中獲取token的方式。首先咱們看重寫了哪些處理器:
com.muggle.poseidon.handler.security.PoseidonAccessDeniedHandler
鑑權失敗處理器;com.muggle.poseidon.handler.security.PoseidonAuthenticationFailureHandler
登陸失敗處理器;com.muggle.poseidon.handler.security.PoseidonAuthenticationSuccessHandler
登陸成功處理器;com.muggle.poseidon.handler.security.PoseidonLoginUrlAuthenticationEntryPoint
未登陸處理器;com.muggle.poseidon.handler.security.PoseidonLogoutSuccessHandler
登出成功處理器。以上幾個處理器都是返回json的數據,若是須要修改json格式或者須要改爲重定向的方式,須要手動去找到相關處理器去修改;由於這部分相關工做(好比重定向或者提示信息)均可以在前端解決,因此這裏未作擴展處理。
而後是 token過濾器 com.muggle.poseidon.filter.SecurityTokenFilter
,該過濾器會首先從請求頭中獲取token,若是獲取失敗則會從cookie 中獲取token,key都是 token,獲取到token後調用 securityStore.getUserdetail(String token)
獲得一個 UserDetails
,所以,怎麼經過token獲取用戶信息須要使用者本身去擴展,你能夠直接從數據庫中讀,或者從緩存中讀,或者直接就像jwt那樣,經過解析token生成。在接下來的鑑權流程中。會從該 UserDetails
中獲取 GrantedAuthority
集合 和 url 一併傳遞給 rooleMatch(Collection<? extends GrantedAuthority> authorities, String path)
去鑑權(若是匹配爲 IgnorePath 則不鑑權直接經過)。這裏的鑑權方案也是須要使用者去本身實現,鑑權方案確定是經過匹配url來實現,那麼怎麼去匹配設計方案就不少了,這裏提供幾個思路:
spring.profiles.include=refresh
的時候會去獲取項目中的全部url和相關的swagger註釋。交給 TokenService.processUrl(List<AuthUrlPathDO> list)
去處理,你能夠保存到數據庫,爲後續鑑權提供依據。GrantedAuthority
進行直接匹配,經過規則咱們就能直接判斷哪些用戶是有權限訪問的了。在 TokenService
和 SecurityStore
中還有其餘相關的方法,如登入登出等,這裏不作介紹了,請參看源碼註釋。
統一異常處理相關的類是 WebResultHandler
它定義了一些異常信息的處理策略。若是你不想要這些策略能夠直接刪掉它,或者本身從新注入一個異常處理器,若是你想擴展它,那麼你能夠參考項目中readme.md文檔中的案例:
@RestControllerAdvice
@Configuration
public class MyWebResultHandler extends WebResultHandler {
private static final Logger log = LoggerFactory.getLogger(OAwebResultHandler.class);
@ExceptionHandler({ConstraintViolationException.class})
public ResultBean methodArgumentNotValidException(ConstraintViolationException e, HttpServletRequest req) {
log.error("參數未經過校驗", e);
ResultBean error = ResultBean.error(e.getConstraintViolations().iterator().next().getMessage());
return error;
}
}複製代碼
須要注意的一個地方,若是咱們項目中出現了未知的異常,應該要引發重視,所以當發生未知異常的時候會拋出一個事件。使用者能夠註冊監聽器來監聽這個事件,當發生未知的異常的時候能夠及時的通知到開發人員,示例:
@Component
public class ExceptionListener implements ApplicationListener<ExceptionEvent> {
@Override
public void onApplicationEvent(ExceptionEvent event) {
String message = event.getMessage();
// TODO 將異常信息投遞到郵箱等,通知開發人員系統異常,儘快處理。
}
}
複製代碼
想要使用請求日誌的功能須要實現 DistributedLocker
接口並註冊到spring容器中以激活日誌切面。而後再須要攔截的方法上加上 @InterfaceAction
當咱們請求這個方法時就會以info級別將請求參數輸入到日誌中,目前日誌格式是寫死的,格式形如:
INFO com.muggle.poseidon.aop.RequestAspect - 》》》》》》 請求日誌 用戶名:用戶未登陸 url=/user/regester.jsonmethod=POSTip=127.0.0.1host=127.0.0.1port=57180classMethod=com.muggle.poseidon.oa.controller.UserController.regesterparamters [ (OaUserVO(gender=1, username=muggle, password=xxxxxx, email=null, imgUrl=null)) ]複製代碼
若是想作冪等攔截 則須要在註解上添加參數 @InterfaceAction(Idempotent = true,message = "請求太頻繁,請稍後再試")
,Idempotent
是否開啓冪等攔截, message
是 被攔截後的提示信息,expertime
是冪等鎖時長 。開啓攔截後會 拼接一個 key String key = "lock:idempotent:" + request.getRequestURI() + ":" + username + ":" + RequestUtils.getIP(request);
而後調用 DistributedLocker.trylock(String key, Long express)
方法進行上鎖,express
參數就是註解上配置 expertime
,上鎖方式須要使用者本身實現,你能夠用redis,zookeeper,或者緩存來上鎖。
部分使用者可能但願能把請求相關的信息存儲到數據庫,我也提供了擴展接口:RequestLogProcessor
只要實現該接口並註冊到 spring 你就能在recordBefore
方法中拿到 請求相關信息 ,在recordAfterReturning
方法中拿到返回值,注意若是方法拋出異常,是不會拿到返回值的,須要本身去修改源碼添加異常切面方法,異常切面方法的註解是 @AfterThrowing
。
日誌配置主要是兩個地方,一個是 banner.txt
另一個是 poseidon-logback.xml
若是小夥伴不喜歡這個banner想去掉,只須要在本身的項目中添加一個 banner.txt
進行覆蓋就好了。
poseidon-logback.xml
是對日誌格式等的配置,經過 logging.config=classpath:poseidon-logback.xml
來啓用該配置,同時須要指定日誌文件輸出路徑 log.dir=/temp/xxx
,啓用該配置後你就能夠在控制檯上看到五彩斑斕的黑,若是小夥伴不喜歡這個配色,能夠根據配置文件中的註釋去修改。
作出查詢配置這個功能是爲了減小平時開發寫查詢接口的開發成本,這個功能自己是結合 mybatis 的 pagehelper
插件使用的,若是你沒有用這個插件,那就享受不到這個福利了。
因爲各個公司或者的查詢要求不盡相同,因此這裏我也只作了一個頂層抽象。具體查詢策略仍是須要開發者去實現,將擴展性預留了出來。下面介紹這個功能的思路。
查詢bean的 頂層抽象爲 com.muggle.poseidon.base.BaseQuery
,這裏面定義查詢的一些通用屬性。而後在 com.muggle.poseidon.aop.QueryAspect
中攔截查詢方法,攔截規則是類名必需要以 Controller
結尾,入參必須是 BaseQuery
的子類。
這個切面是沒有註冊的,須要手動註冊一下:
@Bean
QueryAspect getQueryAspect(){
return new QueryAspect();
}複製代碼
在切面的 doBefore(JoinPoint joinPoint)
中 對查詢參數進行轉化,在doAfterReturning(JoinPoint joinPoint, Object result)
對查詢的返回值進行再次處理。實際使用中小夥伴就根據項目需求進行擴展吧。
com.muggle.poseidon.util
收集了一些工具類,小夥伴們請按需增刪。com.muggle.poseidon.base
包下的 com.muggle.poseidon.base.ResultBean
是對 controller
層的返回值的bean的封裝。exception
包下是自定義異常的頂層抽象類。
目前項目只發布了 BETA 版,後續不會再在這個版本上加新功能,當版本穩定後,我會在這個版本基礎上發佈一個 REALSE 版本。若是小夥伴發現bug,或者有改進意見,或者對這個項目有新的需求請務必聯繫我,擼碼不易,點個star支持一下吧,球球了。