`
dannyhz
  • 浏览: 395228 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

spring 4 value annotation的使用

 
阅读更多
http://www.jb51.net/article/123012.htm

引用


前言
本文主要给大家介绍了关于Spring4自定义@Value功能的相关内容,使用的Spring版本4.3.10.RELEASE,下面话不多说了,来一起看看详细的介绍吧。
@Value在Spring中,功能非常强大,可以注入一个配置项,可以引用容器中的Bean(调用其方法),也可以做一些简单的运算
如下的一个简单demo,演示@Value的用法
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import org.springframework.stereotype.Service;
 
/**
* 测试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 {
  
/**
  * 引用一个配置项
  */
@Value("${app.port}")
private int port;
  
/**
  * 调用容器的一个bean的方法获取值
  */
@Value("#{userService.count()}")
private int userCount;
  
/**
  * 调用容器的一个bean的方法,且传入一个配置项的值作为参数
  */
@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();
}
}
运行,输出结果
port : 9090
userCount : 10
max : 10
min : 3
一般的用法就是这样,用于注入一个值。
那么,能否做到,我给定一个表达式或者具体的值,它能帮忙计算出表达式的值呢? 也就是说,实现一个@Value的功能呢?
方法如下:
?
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();
  
/**
  * 解析一个表达式,获取一个值
  * @param beanFactory
  * @param 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();
}
}
运行输出如下:
1121
9090
10
10
3
发现已经实现了@Value的功能
最后,可能有人就有疑问了,这有什么用呢?我直接用@Value难道不好吗?
对于大部分场景下,的确直接用@Value就可以了。但是,有些特殊的场景,@Value做不了
比如说,我们定义一个注解
?
1
2
3
4
5
@Retention(RUNTIME)
@Target(TYPE)
public @interface Job {
String cron();
}
这个注解需要一个cron的表达式,我们的需求是,使用方可以直接用一个cron表达式,也可以支持引用一个配置项(把值配置到配置文件中)
比如说
?
1
2
@Job(cron = "0 0 12 * * ?")
@Job(cron = "${app.job.cron}")
这种情况@Value就做不到,但是,可以用我上面的解决方案。



分享到:
评论

相关推荐

    Spring annotation

    - `@RunWith(SpringRunner.class)`: 使用Spring JUnit支持运行测试类。 - `@SpringBootTest`: 创建一个Spring Boot应用上下文,可用于测试整个应用。 - `@WebMvcTest`: 专注于Spring MVC层的测试,只启动Web相关...

    配置整合DWR3.0和Spring2.5使用annotation注解

    在本文中,我们将探讨如何将Direct Web Remoting (DWR) 3.0与Spring 2.5框架整合,并利用注解(Annotation)进行配置。DWR是一个允许JavaScript与Java服务器端进行交互的库,而Spring 2.5引入了对注解的强大支持,...

    Spring的Annotation配置相关讲义

    在Spring框架中,Annotation配置是一种简洁且强大的方式来管理Bean的定义和依赖注入,它消除了传统的XML配置文件,使得代码更加简洁、易读。在Spring 3.0及以上版本中,Annotation配置得到了广泛的应用。 首先,...

    Spring IOC Annotation 注入 学习实例

    在`IOC_Project`这个压缩包文件中,很可能是包含了一个示例项目,用于演示如何使用Spring的IOC Annotation注入。通过查看和运行这个项目,你可以更深入地了解这些概念并实践它们。项目的结构可能包括了源代码文件(`...

    扩展Spring—使用Annotation将配置资源注入到Bean中

    在Spring框架中,注解(Annotation)的使用极大地简化了传统XML配置的复杂性,使得开发者可以更加专注于业务逻辑的实现。本篇文章将深入探讨如何通过注解将配置资源注入到Bean中,以此来理解Spring的注解驱动开发。 ...

    spring的annotation-driven配置事务管理器详解 (多数据源配置

    4. 在 Spring 3.0 及其后的版本中,`@Transactional` 注解支持 value 属性,可以用来特殊指定事务管理器。 5. 如果 `@Transactional` 注解不带参数,默认会使用容器中缺省的事务管理器。 6. 如果 `@Transactional` ...

    spring使用annotation整合dwr笔记

    ### Spring使用Annotation整合DWR知识点解析 #### 一、概览 在现代Web开发中,Direct Web Remoting(简称DWR)是一种简化Ajax应用开发的技术,它允许JavaScript直接调用服务器端的Java方法,而无需编写复杂的XML...

    spring_annotation maven 的配置

    Spring Annotation和Maven的结合使用是现代Java项目中常见的配置方式,它们为开发者提供了高效、灵活的开发环境。本篇文章将深入探讨Spring注解和Maven的配置及其重要性。 **Spring注解** Spring注解是Spring框架...

    spring3,hibernate4 配置声明式事务管理(annotation方式)

    最后,我们可以在测试类中使用`@RunWith(SpringJUnit4ClassRunner.class)`和`@ContextConfiguration`注解来加载Spring配置,并进行事务相关的测试。 总的来说,Spring 3和Hibernate 4结合使用声明式事务管理,使得...

    spring中aop的简单使用(Annotation方式)

    4. **定义通知**:在切面类中,我们可以定义通知方法,并使用`@Before`、`@After`、`@AfterReturning`、`@AfterThrowing`或`@Around`注解来指定其执行时机。 ```java @Before("serviceMethods()") public void ...

    springAnnotation.zip

    4. `@Value`:允许你直接在字段或方法上注入值,可以是硬编码的字符串,也可以是从属性文件中读取的值。 5. `@Scope`:定义bean的作用范围,如`singleton`(单例)和`prototype`(原型)。 6. `@PostConstruct` 和...

    Annotation Based Spring MVC Basics

    我们需要添加一个名为`spring-mvc`的Servlet定义,使用`org.springframework.web.servlet.DispatcherServlet`作为Servlet类。`load-on-startup`元素设置为1,表示该Servlet将在Web应用程序启动时加载。`servlet-...

    Spring Security Annotation tutorial

    - 使用 `@PreAuthorize` 注解时,确保 Spring Security 已经正确配置并加载。 - 在方法执行前,Spring Security 会检查当前认证用户是否满足指定条件。如果不满足,则抛出 `AccessDeniedException` 异常。 - `@...

    spring_core_annotation:注释弹簧

    4. **@Qualifier**: 与@Autowired一起使用,用于在有多个相同类型的Bean时,指定具体要注入哪一个。例如,如果有两个DataSource Bean,可以通过@Qualifier("dataSource1")来指定注入哪一个。 5. **@Value**: 用于...

    Spring Annotation (注解)详解

    6. **Spring的注解支持** - 除了`@Component`、`@Service`、`@Controller`和`@Autowired`,Spring还提供了一系列其他注解,如`@Repository`(用于数据访问层)、`@Value`(注入值)、`@Scope`(指定Bean的作用域)、...

    spring log4j 实例

    Spring框架是Java领域广泛使用的轻量级框架,而Log4j则是日志记录领域的经典工具,提供了丰富的日志配置和管理功能。本实例结合Spring和Log4j,将为你提供一个实用的日志解决方案。 首先,我们要理解Spring是如何...

    Spring 使用注解配置使用ehcache

    本文将深入探讨如何在Spring中使用注解来配置Ehcache。 首先,我们需要在项目中引入Ehcache的相关依赖。如果你使用的是Maven,可以在pom.xml文件中添加以下依赖: ```xml &lt;groupId&gt;net.sf.ehcache&lt;/groupId&gt; ...

    spring中自定义注解(annotation)与AOP中获取注解

    在Spring框架中,自定义注解(Annotation)和AOP(面向切面编程)的结合使用,极大地增强了代码的可读性和可维护性。本文将深入探讨如何在Spring中创建自定义注解以及如何在AOP中有效地获取并利用这些注解。 首先,...

    SpringMVC-Annotation

    但在现代Spring项目中,我们倾向于使用注解来减少XML配置。例如,`@Controller`用于标记一个类作为处理HTTP请求的控制器,`@RequestMapping`用于定义请求映射,`@Autowired`用于自动装配依赖。 2. **@Controller**...

Global site tag (gtag.js) - Google Analytics