当前位置:网站首页>Use spiel expressions in custom annotations to dynamically obtain method parameters or execute methods
Use spiel expressions in custom annotations to dynamically obtain method parameters or execute methods
2022-07-26 10:15:00 【Whale-52 Hz】
Used in custom annotations SpEL expression , Get method parameters or execute methods dynamically
SpEL Expressions have been used for a long time , I feel very tall , But I haven't learned more about how to use it . Basically, they are packaged by some open source projects .
1 SpEL Common usage of
1.1 Get variable
Get the function of variables , The more common usage is spring The function of caching annotations in . You can dynamically obtain the value of parameters in the method . as follows :
@Cacheable(value = "cacheKey",key = "#key")
public String getName(String key) {
return "name";
}
1.2 Execution method
This example has been used spring security Or similar authorization framework may be familiar . as follows
@PreAuthorize("hasRole('ROLE_ADMIN')")
public void addUser(User user) {
System.out.println("addUser................" + user);
}
In fact, this is to execute a class through expressions hasRole Method , Parameter is ’ROLE_ADMIN’, Then get the return value and carry out subsequent operations .
1.3 Other uses
Expressions not only support getting properties and executing methods , It also supports various operator operations , You can find many other great gods . I won't do that here
2 Run the expression by yourself
Write demo Before that, I will briefly introduce several important classes when executing expressions
| Class name | describe |
|---|---|
| ExpressionParser | The expression parser , Mainly used to produce expressions |
| Expression | Expression object |
| EvaluationContext | The context in which the expression runs . Contains the parameters of the expression runtime , And the classes that need to execute methods |
2.1 Get variable
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
/** * * @Author: dong * @Date: 2022/6/23 10:25 */
public class Demo {
public static void main(String[] args) {
// expression parser
ExpressionParser parser = new SpelExpressionParser();
// Parse an expression
Expression expression = parser.parseExpression("#user.name");
// Start preparing the expression runtime
EvaluationContext ctx = new StandardEvaluationContext();
ctx.setVariable("user", new User(" Three Kan "));
String value = expression.getValue(ctx, String.class);
System.out.println(value);
}
public static class User{
private String name;
public User(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
}
Last obtained value Is the value passed in , This demo You can already get user Of name Property value .
2.2 Execution method
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
/** * * @Author: dong * @Date: 2022/6/23 10:25 */
public class Demo {
public static void main(String[] args) {
ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("getInput()");
StandardEvaluationContext ctx = new StandardEvaluationContext();
User user = new User(" Three Kan ");
// Set the class that needs to execute the method
ctx.setRootObject(user);
String value = expression.getValue(ctx, String.class);
System.out.println(value);
}
public static class User{
private String name;
public User(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public String getInput(){
return " My name is :"+this.name;
}
}
}
above demo The result of the operation is “ My name is : Three Kan ”, That is to call getInput Result of method
3 Customize the annotation and pass SpEL Get parameter value
demo Yes, it is java Dynamic proxy implementation of , Therefore, there will be an additional step in the middle that requires the conversion of interface methods into implementation class methods ,springAOP It can be ignored .
User class
public class User {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
Custom annotation
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface GetVal{
String spel();
}
Interface class and its implementation class
public interface Run {
void run(User user);
}
public class RunImpl implements Run {
@GetVal(spel = "#user.name")
@Override
public void run(User user) {
System.out.println(user.getName() + " Running ");
}
}
proxy class
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/** * * @Author: dong * @Date: 2022/6/23 13:46 */
public class RunProxy implements InvocationHandler {
private Object target;
public RunProxy(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// because demo The dynamic proxy of cannot get the formal parameter name using the interface , So convert to the method object of the implementation class
method = target.getClass().getMethod(method.getName(), method.getParameterTypes());
Object res = method.invoke(target, args);
DefaultParameterNameDiscoverer defaultParameterNameDiscoverer = new DefaultParameterNameDiscoverer();
// The reference here is org.springframework.context.expression.MethodBasedEvaluationContext.lazyLoadArguments
String[] parameterNames = defaultParameterNameDiscoverer.getParameterNames(method);
GetVal annotation = method.getAnnotation(GetVal.class);
ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression(annotation.spel());
StandardEvaluationContext ctx = new StandardEvaluationContext();
// Fill in the expression context
for(int i=0;i<parameterNames.length;i++){
ctx.setVariable(parameterNames[i],args[i]);
}
String value = expression.getValue(ctx, String.class);
// Print log
System.out.println(value+" Yes "+method.getName());
return res;
}
}
Began to run
public static void main(String[] args) {
User user = new User(" Three Kan ");
RunImpl runImpl = new RunImpl();
RunProxy proxy = new RunProxy(runImpl);
Run run = (Run) Proxy.newProxyInstance(runImpl.getClass().getClassLoader(), runImpl.getClass().getInterfaces(), proxy);
run.run(user);
}
You can see the following information at the console input :
Connected to the target VM, address: '127.0.0.1:54442', transport: 'socket'
Sankan is running
Three Kan execution run
Disconnected from the target VM, address: '127.0.0.1:54442', transport: 'socket'
Process finished with exit code 0
combination springAOP+SpEL You can realize richer functions
边栏推荐
- Learning about tensorflow (I)
- Use of pclint in vs2013
- Solve the problem of storing cookies in IE7 & IE8
- Flask框架初学-04-flask蓝图及代码抽离
- 数通基础-网络基础知识
- Sqoop【付诸实践 02】Sqoop1最新版 全库导入 + 数据过滤 + 字段类型支持 说明及举例代码(query参数及字段类型强制转换)
- Study notes at the end of summer vacation
- IEEE conference upload font problem
- Wechat H5 payment on WAP, for non wechat browsers
- How to write a million reading article
猜你喜欢

Server memory failure prediction can actually do this!

The charm of SQL optimization! From 30248s to 0.001s

Uniapp "no mobile phone or simulator detected, please try again later" and uniapp custom components and communication

Data communication foundation TCPIP reference model

The practice of OpenCV -- bank card number recognition

数通基础-STP原理
![Sqoop [environment setup 01] CentOS Linux release 7.5 installation configuration sqoop-1.4.7 resolve warnings and verify (attach sqoop 1 + sqoop 2 Latest installation package +mysql driver package res](/img/8e/265af6b20f79b21c3eadcd70cfbdf7.png)
Sqoop [environment setup 01] CentOS Linux release 7.5 installation configuration sqoop-1.4.7 resolve warnings and verify (attach sqoop 1 + sqoop 2 Latest installation package +mysql driver package res

新建福厦铁路全线贯通 这将给福建沿海带来什么?

点赞,《新程序员》电子书限时免费领啦!

Solve proxyerror: CONDA cannot proceed due to an error in your proxy configuration
随机推荐
Wu Enda linear regression of machine learning
Reproduce the snake game in C language (I) build pages and construct snakes
Leetcode 504. 七进制数
Common errors when starting projects in uniapp ---appid
论文笔记(SESSION-BASED RECOMMENDATIONS WITHRECURRENT NEURAL NETWORKS)
Distributed network communication framework: how to publish local services into RPC services
PHP one-time request lifecycle
How to use Gmail to pick up / send mail on Foxmail
数通基础-网络基础知识
Sqoop【环境搭建 01】CentOS Linux release 7.5 安装配置 sqoop-1.4.7 解决警告并验证(附Sqoop1+Sqoop2最新版安装包+MySQL驱动包资源)
Introduction to latex, EPS picture bounding box
Keeping alive to realize MySQL automatic failover
Rocky basic exercise -shell script 2
Tableviewcell highly adaptive
Transform between tree and array in JS (hide the children field if the child node of the tree is empty)
Necessary for beginners: debug breakpoint debugging skills in idea and common breakpoint skills
protobuf的基本用法
Write a script that can run in Bash / shell and PowerShell
Data communication foundation - layer 2 switching principle
Principle analysis and source code interpretation of service discovery