Spring AOP如何在注解上使用SPEL表達(dá)式注入對象
在注解上使用SPEL表達(dá)式注入對象
場景描述
在平時開發(fā)中,我們經(jīng)常通過定義一些注解,進(jìn)行輕量級開發(fā)。
今天主要研究的內(nèi)容是關(guān)于如何在注解上通過spel表達(dá)式注入對象,以此調(diào)用注入對象的具體業(yè)務(wù)處理邏輯,然后在通過對表達(dá)式的解析,進(jìn)而獲取該業(yè)務(wù)邏輯處理的結(jié)果,類似于Spring Security中的@PreAuthorize, @PreAuthorize, @PostAuthorize等注解,本次場景案例以模仿@PreAuthorize注解進(jìn)行分析。
具體案例
定義@SpelPreAuthorize注解,對標(biāo)@PreAuthorize
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SpelPreAuthorize {
? ? String value() default "";
}定義具體業(yè)務(wù)邏輯處理類
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);
? ? } ? ??
}定義切面
- 通過@Before注解定義前置切面
- 通過注入spelExpressionParser解析器,用于解析spel表達(dá)式
- 實例化EvaluationContext對象(默認(rèn)實現(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();
? ? ? ? // 實例化spel表達(dá)式解析器
? ? ? ? SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
? ? ? ? // 解析表達(dá)式內(nèi)容
? ? ? ? Expression expression = spelExpressionParser.parseExpression(permission);
? ? ? ? // 聲明StandardEvaluationContext對象,用于設(shè)置上下文對象。
? ? ? ? StandardEvaluationContext context = new StandardEvaluationContext();
? ? ? ? context.setBeanResolver(new BeanFactoryResolver(defaultListableBeanFactory));
? ? ? ? Boolean result = expression.getValue(context, Boolean.class);
? ? ? ? if (!result) {
? ? ? ? ? ? throw new RuntimeException("該用戶無訪問權(quán)限");
? ? ? ? }
? ? }
}定義測試類
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á)式的好處就是,我們可以使用定義好的某個類中的方法來產(chǎn)生值,然后注入給所需要的對象使用
比較適用于比較復(fù)雜的bean注入
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
- Spring中@Value使用詳解及SPEL表達(dá)式
- 詳解Spring中Spel表達(dá)式和el表達(dá)式的區(qū)別
- SpringDataElasticsearch與SpEL表達(dá)式實現(xiàn)ES動態(tài)索引
- spring之SpEL表達(dá)式詳解
- 使用Springboot自定義注解,支持SPEL表達(dá)式
- 基于spring?@Cacheable?注解的spel表達(dá)式解析執(zhí)行邏輯
- Spring?Cache抽象-使用SpEL表達(dá)式解析
- Spring實戰(zhàn)之Bean定義中的SpEL表達(dá)式語言支持操作示例
- Spring組件開發(fā)模式支持SPEL表達(dá)式
- Spring spel表達(dá)式使用方法示例
- Spring中SpEL表達(dá)式的使用全解
相關(guān)文章
Java技能點之SimpleDateFormat進(jìn)行日期格式化問題
這篇文章主要介紹了Java技能點之SimpleDateFormat進(jìn)行日期格式化問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04
spring中jdbcTemplate.batchUpdate的幾種使用情況
本文主要介紹了spring中jdbcTemplate.batchUpdate的幾種使用情況,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04
JpaRepository如何實現(xiàn)增刪改查并進(jìn)行單元測試
這篇文章主要介紹了JpaRepository如何實現(xiàn)增刪改查并進(jìn)行單元測試,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
Java輸入流Scanner/BufferedReader使用方法示例
這篇文章主要介紹了Java輸入流Scanner/BufferedReader使用方法,大家看示例吧2013-11-11
Java實現(xiàn)公用實體類轉(zhuǎn)Tree結(jié)構(gòu)
這篇文章主要為大家介紹了一個Java工具類,可以實現(xiàn)Java公用實體類轉(zhuǎn)Tree結(jié)構(gòu),文中的示例代碼簡潔易懂,感興趣的小伙伴可以參考一下2024-10-10
Mybatis開發(fā)要點-resultType和resultMap有什么區(qū)別詳解
本文主要介紹了Mybatis開發(fā)要點-resultType和resultMap有什么區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04

