The use of spring 4 value annotation

http://www.jb51.net/article/123012.htm

quote


Preface
This article mainly introduces the relevant content about Spring4's custom @Value function, using Spring version 4.3.10.RELEASE, I won't say much more, let's take a look at the detailed introduction.
@Value is very powerful in Spring. It can inject a configuration item, refer to the bean in the container (call its method), or do some simple operations. The
following simple demo demonstrates the usage of @Value
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import org.springframework.stereotype.Service;
 
/**
* Test Bean
*/
@Service("userService")
public class UserService {
 
public int count() {
  return 10 ;
}
  
public int max(int size) {
  int count = count();
  return count > size ? count : size;
}
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
 
@Component
public class AppRunner implements InitializingBean {
  
/**
  * Refers to a configuration item
  */
@Value("${app.port}")
private int port;
  
/**
  * Call a bean method of the container to get the value
  */
@Value("#{userService.count()}")
private int userCount;
  
/**
  * Call the method of a bean of the container, and pass in the value of a configuration item as a parameter
  */
@Value("#{userService.max(${app.size})}")
private int max;
  
/**
  * 简单的运算
  */
@Value("#{${app.size} <= '12345'.length() ? ${app.size} : '12345'.length()}")
private int min;
  
//测试
public void afterPropertiesSet() throws Exception {
  System.out.println("port : " + port);
  System.out.println("userCount : " + userCount);
  System.out.println("max : " + max);
  System.out.println("min : " + min);
}
}
app.properties
?
1
2
3
app.port=9090
 
app.size=3
?
1
2
3
4
5
6
7
8
9
10
11
12
13
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;
 
@ComponentScan
@PropertySource("classpath:app.properties")
public class App {
  
public static void main( String[] args) {
  AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(App.class);
  context.close();
}
}
run, output result
port : 9090
userCount : 10
max : 10
min : 3
The general usage is like this, for injecting a value.
So, can it be done, given an expression or a specific value, it can help to calculate the value of the expression? That is, what about implementing a @Value function?
The method is as follows:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import org.springframework.beans.factory.config.BeanExpressionContext;
import org.springframework.beans.factory .config.BeanExpressionResolver;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.expression.StandardBeanExpressionResolver;
 
public class ValueUtil {
 
private static final BeanExpressionResolver resolver = new StandardBeanExpressionResolver();
  
/**
  * Parse an expression and get a value
  * @param beanFactory
  * @param value A fixed value or an expression. If it is a fixed value, return the fixed value directly, otherwise resolve an expression and return the resolved value
  * @return
  */
public static Object resolveExpression(ConfigurableBeanFactory beanFactory, String value) {
  String resolvedValue = beanFactory.resolveEmbeddedValue(value);
   
  if (!(resolvedValue.startsWith("#{") && value.endsWith("}"))) {
   return resolvedValue;
  }
   
  return resolver.evaluate(resolvedValue, new BeanExpressionContext(beanFactory, null));
}
}
具体使用如下:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;
 
@ComponentScan
@PropertySource("classpath:app.properties")
public class App {
  
public static void main( String[] args) {
  AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(App.class);
  //计算一个具体的值(非表达式)
  System.out.println(ValueUtil.resolveExpression(context.getBeanFactory(), "1121"));
  //实现@Value的功能
  System.out.println(ValueUtil.resolveExpression(context.getBeanFactory(), "${app.port}"));
  System.out.println(ValueUtil.resolveExpression(context.getBeanFactory(), "#{userService.count()}"));
  System.out.println(ValueUtil.resolveExpression(context.getBeanFactory(), "#{userService.max(${app.size})}"));
  System.out.println(ValueUtil.resolveExpression(context.getBeanFactory(), "#{${app.size} <= '12345'.length() ? ${app.size} : '12345'.length()} "));
  context.close();
}
} The
output of running is as follows:
1121
9090
10
10
3
It is found that the function of @Value has been implemented
Finally , some people may have doubts, what is the use of this? Wouldn't it be bad for me to just use @Value?
For most scenarios, you can indeed use @Value directly. However, in some special cases, @Value cannot do it.
For example , we define an annotation
?
1
2
3
4
5
@Retention(RUNTIME)
@Target(TYPE)
public @interface Job {
String cron();
}
This annotation requires a cron The expression, our requirement is that the user can directly use a cron expression, or can support a configuration item (configure the value into the configuration file)
For example
?
1
2
@Job(cron = "0 0 12 * * ?")
@Job(cron = "${app.job.cron}")
@Value can't do this, but you can use me above solution.



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326070175&siteId=291194637