Spring AOP如何在注解上使用SPEL表達(dá)式注入對(duì)象
在注解上使用SPEL表達(dá)式注入對(duì)象
場(chǎng)景描述
在平時(shí)開(kāi)發(fā)中,我們經(jīng)常通過(guò)定義一些注解,進(jìn)行輕量級(jí)開(kāi)發(fā)。
今天主要研究的內(nèi)容是關(guān)于如何在注解上通過(guò)spel表達(dá)式注入對(duì)象,以此調(diào)用注入對(duì)象的具體業(yè)務(wù)處理邏輯,然后在通過(guò)對(duì)表達(dá)式的解析,進(jìn)而獲取該業(yè)務(wù)邏輯處理的結(jié)果,類(lèi)似于Spring Security中的@PreAuthorize, @PreAuthorize, @PostAuthorize等注解,本次場(chǎng)景案例以模仿@PreAuthorize注解進(jìn)行分析。
具體案例
定義@SpelPreAuthorize注解,對(duì)標(biāo)@PreAuthorize
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface SpelPreAuthorize { ? ? String value() default ""; }
定義具體業(yè)務(wù)邏輯處理類(lèi)
import org.springframework.stereotype.Component; import java.util.Arrays; import java.util.List; @Component("ps") public class PermissionService { ? ? ? ? public boolean hasPermission(String permission) { ? ? ? ? List<String> allPermissions = Arrays.asList("user:save", "user:delete", "user:edit"); ? ? ? ? return allPermissions.contains(permission); ? ? } ? ?? }
定義切面
- 通過(guò)@Before注解定義前置切面
- 通過(guò)注入spelExpressionParser解析器,用于解析spel表達(dá)式
- 實(shí)例化EvaluationContext對(duì)象(默認(rèn)實(shí)現(xiàn)tandardEvaluationContext),解析表達(dá)式,注入上下文信息,執(zhí)行具體業(yè)務(wù)
import com.czf.ebao.data.spel.annoation.SpelPreAuthorize; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.expression.BeanFactoryResolver; import org.springframework.expression.Expression; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.stereotype.Component; @Component @Aspect public class SpelPreAuthorizeAspect { ? ? /** ? ? ?* 注入spring bean 工廠 ? ? ?*/ ? ? @Autowired ? ? private DefaultListableBeanFactory defaultListableBeanFactory; ? ? @Before("@annotation(spelPreAuthorize)") ? ? public void perAuthorize(JoinPoint point, SpelPreAuthorize spelPreAuthorize) { ? ? ? ? String permission = spelPreAuthorize.value(); ? ? ? ? // 實(shí)例化spel表達(dá)式解析器 ? ? ? ? SpelExpressionParser spelExpressionParser = new SpelExpressionParser(); ? ? ? ? // 解析表達(dá)式內(nèi)容 ? ? ? ? Expression expression = spelExpressionParser.parseExpression(permission); ? ? ? ? // 聲明StandardEvaluationContext對(duì)象,用于設(shè)置上下文對(duì)象。 ? ? ? ? StandardEvaluationContext context = new StandardEvaluationContext(); ? ? ? ? context.setBeanResolver(new BeanFactoryResolver(defaultListableBeanFactory)); ? ? ? ? Boolean result = expression.getValue(context, Boolean.class); ? ? ? ? if (!result) { ? ? ? ? ? ? throw new RuntimeException("該用戶(hù)無(wú)訪問(wèn)權(quán)限"); ? ? ? ? } ? ? } }
定義測(cè)試類(lèi)
import com.czf.ebao.data.spel.annoation.SpelPreAuthorize; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/spel") public class SpelController { ? ?? ? ? @GetMapping("/hello") ? ? @SpelPreAuthorize("@pms.hasPermission('user:hello')") ? ? public String sayHello() { ? ? ? ? return "hello"; ? ? } }
補(bǔ)充
通配符匹配
// import org.springframework.util.PatternMatchUtils List<String> allPermissions = Arrays.asList("user:save", "user:delete", "user:edit"); return allPermissions.stream().anyMatch(item -> PatternMatchUtils.simpleMatch(permission, item));
Spring屬性注入方式之SPEL表達(dá)式
<bean id="categroy" class="com.test.inject.Category" p:cateName="服裝"></bean> <bean id="calculate" class="com.test.inject.PriceCalculate"></bean> <bean id="product" class="com.test.inject.Product" p:name="A21的T恤" p:categroy-ref="categroy"> <property name="price" value="#{calculate.calPrice()}"></property> </bean>
spel表達(dá)式的好處就是,我們可以使用定義好的某個(gè)類(lèi)中的方法來(lái)產(chǎn)生值,然后注入給所需要的對(duì)象使用
比較適用于比較復(fù)雜的bean注入
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Spring中@Value使用詳解及SPEL表達(dá)式
- 詳解Spring中Spel表達(dá)式和el表達(dá)式的區(qū)別
- SpringDataElasticsearch與SpEL表達(dá)式實(shí)現(xiàn)ES動(dòng)態(tài)索引
- spring之SpEL表達(dá)式詳解
- 使用Springboot自定義注解,支持SPEL表達(dá)式
- 基于spring?@Cacheable?注解的spel表達(dá)式解析執(zhí)行邏輯
- Spring?Cache抽象-使用SpEL表達(dá)式解析
- Spring實(shí)戰(zhàn)之Bean定義中的SpEL表達(dá)式語(yǔ)言支持操作示例
- Spring組件開(kāi)發(fā)模式支持SPEL表達(dá)式
- Spring spel表達(dá)式使用方法示例
- Spring中SpEL表達(dá)式的使用全解
相關(guān)文章
spring中@Autowire和@Resource的區(qū)別在哪里(推薦)
這篇文章主要介紹了spring中@Autowire和@Resource的區(qū)別在哪里?本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-02-02java根據(jù)圖片中綠色像素點(diǎn)的多少進(jìn)行排序
這篇文章主要介紹了java根據(jù)圖片中綠色像素點(diǎn)的多少進(jìn)行排序,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03springboot整合flowable框架入門(mén)步驟
最近工作中有用到工作流的開(kāi)發(fā),引入了flowable工作流框架,在此記錄一下springboot整合flowable工作流框架的過(guò)程,感興趣的朋友一起看看吧2022-04-04java實(shí)現(xiàn)圖片轉(zhuǎn)base64字符串 java實(shí)現(xiàn)base64字符串轉(zhuǎn)圖片
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)圖片轉(zhuǎn)base64字符串,java實(shí)現(xiàn)base64字符串轉(zhuǎn)圖片,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02springcloud微服務(wù)基于redis集群的單點(diǎn)登錄實(shí)現(xiàn)解析
這篇文章主要介紹了springcloud微服務(wù)基于redis集群的單點(diǎn)登錄實(shí)現(xiàn)解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09關(guān)于intellij idea打開(kāi)就閃退或關(guān)閉詳細(xì)解決辦法
這篇文章主要介紹了關(guān)于intellij idea打開(kāi)就閃退或關(guān)閉詳細(xì)解決辦法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03Springboot中的@ConditionalOnBean注解詳細(xì)解讀
這篇文章主要介紹了Springboot中的@ConditionalOnBean注解詳細(xì)解讀,@ConditionalOnMissingBean注解兩個(gè)類(lèi),一個(gè)Computer類(lèi),一個(gè)配置類(lèi),想要完成;如果容器中沒(méi)有Computer類(lèi),就注入備用電腦Computer類(lèi),如果有Computer就不注入,需要的朋友可以參考下2023-11-11