Spring @Value Annotation Example

0

In this article we will see some examples of spring @Value annotation to use it for expression-driven dependency injection.
We will also see how we can use @Value to dynamically resolve handler method parameters in spring MVC.

We will use a test class to demonstrate the use @Value annotation.
Run the class with spring based runner SpringJUnit4ClassRunner so that spring test framework can build the context using the support of some classes and annotation.
For example, an empty @ContextConfiguration loads and configure an ApplicationContext by parsing the current declared test class.

We also want to load some test properties which want to inject later through the @Value annotation. Using @TestPropertySource we configure the property file to be added to the spring environment.

test.properties:

latest=SpringValueAnnotation

The property can be injected to a field using @Value annotation.

@Value("#{environment['latest']}")
private String latestValue;

In @BeforeClass method, we set a system property which we will use it to inject value to a field.

@BeforeClass
public static void configureSystemProperties() {
    System.setProperty("topic", "Spring");
}

We will inject the system property using:

@Value("#{systemProperties.topic}")
private String topicName;

We can also inject a date value using @Value and @DateTimeFormat that defines the date format.

@DateTimeFormat(pattern = "MM-d-yy")
@Value("12-22-09")
private Date dateUsingDateTimeAnnotation;

You can also define a custom date annotation and use that to inject date values. For example,

FormattedDateAnnot:

package com.javarticles.spring;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import org.springframework.format.annotation.DateTimeFormat;

@DateTimeFormat(pattern="MM-d-yy")
@Retention(RetentionPolicy.RUNTIME)
public @interface FormattedDateAnnot {
}

Now use @FormattedDateAnnot to inject a date value.

@FormattedDateAnnot
@Value("10-31-09")
private Date dateUsingCustomAnnotation;

Here is the complete test class.

SpringValueAnnotationTest:

package com.javarticles.spring;

import java.util.Date;

import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.support.FormattingConversionServiceFactoryBean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource("test.properties")
@ContextConfiguration
public class SpringValueAnnotationTest {

    @Value("#{systemProperties.topic}")
    private String topicName;

    @Value("#{environment['latest']}")
    private String latestValue;

    @Value("#{topicBean.name}")
    private String topicNameFromBean;

    @FormattedDateAnnot
    @Value("10-31-09")
    private Date dateUsingCustomAnnotation;

    @DateTimeFormat(pattern = "MM-d-yy")
    @Value("12-22-09")
    private Date dateUsingDateTimeAnnotation;

    @BeforeClass
    public static void configureSystemProperties() {
        System.setProperty("topic", "Spring");
    }

    @Test
    public void injectSysProperty() throws Exception {
        System.out.println("Value of System property 'topic': " + topicName);
    }

    @Test
    public void injectValueProperty() throws Exception {
        System.out.println("Value of key 'latest': " + latestValue);
    }

    @Test
    public void injectBeanProperty() throws Exception {
        System.out.println("Topic name from TopicBean: " + topicNameFromBean);
    }

    @Test
    public void injectDate() throws Exception {
        System.out.println("Date using custom annotation @FormattedDateAnnot: "
                + dateUsingCustomAnnotation);
        System.out.println("Date using @DateTimeFormat: "
                + dateUsingDateTimeAnnotation);
    }

    @Configuration
    static class Config {
        @Bean
        public FormattingConversionServiceFactoryBean conversionService() {
            return new FormattingConversionServiceFactoryBean();
        }
    }

    @Configuration("topicBean")
    public static class TopicBean {
        private String name = "Spring";

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

}

Output:

Value of key 'latest': SpringValueAnnotation
Value of System property 'topic': Spring
Topic name from TopicBean: Spring

Use @Value in Hanlder Method

You can also use @Value annotation in a handler method. For example, in myHandle method we use it to inject the context path.

@Value declaration:

@Value("#{request.contextPath}

The handler method:

        @RequestMapping("/latestExample.do")
        public void myHandle(
                @RequestParam(value = "id", defaultValue = "#{environment['latest']}") String id,
                @Value("#{request.contextPath}") String contextPath,
                HttpServletResponse response) throws IOException {
            response.getWriter().write(contextPath + "/" + String.valueOf(id));
        }
    }

SpringValueInControllerTest:

package com.javarticles.spring;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletConfig;
import org.springframework.stereotype.Controller;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource("test.properties")
@WebAppConfiguration
@ContextConfiguration
public class SpringValueInControllerTest {
    private DispatcherServlet servlet;

    @Autowired
    private WebApplicationContext wac;

    @Value("#{environment['latest']}")
    private String latestExample;

    @Before
    public void setup() throws ServletException {
        initDispatcherServlet();
    }

    private void initDispatcherServlet() throws ServletException {
        servlet = new DispatcherServlet() {
            private static final long serialVersionUID = 1L;

            @Override
            protected WebApplicationContext createWebApplicationContext(
                    WebApplicationContext parent) throws BeansException {
                return wac;
            }
        };
        servlet.init(new MockServletConfig());
    }

    @Test
    public void valueAnnotationUse() throws Exception {
        System.out.println("Latest example: "
                + wac.getEnvironment().getProperty("latest"));
        MockHttpServletRequest request = new MockHttpServletRequest("GET",
                "/examples/latestExample.do");
        request.setContextPath("/examples");
        MockHttpServletResponse response = new MockHttpServletResponse();
        servlet.service(request, response);
        System.out.println(response.getContentAsString());
        Assert.assertEquals("/examples/SpringValueAnnotation",
                response.getContentAsString());
    }

    @Configuration
    @EnableWebMvc
    static class WebConfig extends WebMvcConfigurerAdapter {

        @Bean
        public MyController valueController() {
            return new MyController();
        }
    }

    @Controller
    public static class MyController {

        @RequestMapping("/latestExample.do")
        public void myHandle(
                @RequestParam(value = "id", defaultValue = "#{environment['latest']}") String id,
                @Value("#{request.contextPath}") String contextPath,
                HttpServletResponse response) throws IOException {
            response.getWriter().write(contextPath + "/" + String.valueOf(id));
        }
    }

}

Output:

Latest example: SpringValueAnnotation
/examples/SpringValueAnnotation

Download the source code

This was an example about spring @Value annotation.

You can download the source code here: SpringValueAnnotationExample.zip
Share.

Comments are closed.