Spring Starter (IX): runtime value injection

Spring provides two ways implantation values ​​at run time:

  1. Placeholder property (Property placeholder)
  2. Spring Expression Language (SpEL)

1. Properties placeholder

Injecting external value 1.1

1.1.1 Environment

Under normal circumstances, we will put some values ​​in the configuration file, and then injected into the value of some fields such as the program runs.

If we have a test.properties configuration file, as follows:

book.author=wangyunfei
book.name=spring boot
author.age=30

Now we hope that the program is running, this value is assigned to each field bookAuthor and bookName, then how to achieve it?

First, a new class ExpressiveConfig arranged as follows:

package chapter03.el;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;

@Configuration
@ComponentScan
@PropertySource("classpath:chapter03/el/test.properties")
public class ExpressiveConfig {
    @Autowired
    private Environment environment;

    public void outputResource() {
        System.out.println("book.name:" + environment.getProperty("book.name"));
        System.out.println("book.author:" + environment.getProperty("book.author"));
    }
}

Here we use @PropertySource annotated references test.properties profile, location of this file is located in the chapter03.el package.

This property file will be loaded into the Spring of Environment, and then we can call the getProperty method to get to the property value ().

Main new class, add the following test code in its main () method:

package chapter03.el;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ExpressiveConfig.class);

        ExpressiveConfig expressiveConfig = context.getBean(ExpressiveConfig.class);

        expressiveConfig.outputResource();

        context.close();
    }
}

Run the code found thrown java.io.FileNotFoundExceptionexception, as follows:

As can be seen from the error message, which is not able to find chapter03 / el / test.properties this document, this is why?

With this question, we look at the target directory compiled code, as follows:

As can be seen from the figure, our new test.properties and test.txt file has not been compiled to the next target directory, it will throw an exception.

This is because the location of our new files are placed under chapter03.el package, while IDEA default will not put these files are automatically copied to the target directory, but we can add the following configuration in pom.xml to resolve the problem:

<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.txt</include>
                <include>**/*.properties</include>
            </includes>
        </resource>
    </resources>
</build>

Here we specify the txt file properties and, if necessary, continue to add <include>tags and other specified xml file.

Re-run the test code, the log output as follows:

book.name:spring boot

book.author:wangyunfei

At this point the next target directory already contains our newly created two files:

If the attribute values ​​specified does not exist, getProperty () will return null, as follows:

String workCity = environment.getProperty("author.workcity");
System.out.println("author.workcity:" + workCity);

Output:

author.workcity:null

getProperty () also provides a heavy-duty, when the specified attribute value does not exist, the default values ​​can be specified:

String workCity = environment.getProperty("author.workcity", "上海");
System.out.println("author.workcity:" + workCity);

Output:

author.workcity: Shanghai

If you want to attribute value must exist, you can use getRequiredProperty () method, when the property value does not exist, it will throw an java.lang.IllegalStateExceptionexception:

String workCity = environment.getRequiredProperty("author.workcity");
System.out.println("author.workcity:" + workCity);

getProperty () also provides a heavy-duty, you can specify the type of return value, for example, we want to return Integer type:

Integer authorAge = environment.getProperty("author.age", Integer.class);
System.out.println("author.age:" + authorAge);

Output:

author.age:30

getProperty () also provides a heavy-duty, when the specified attribute value does not exist, not only can specify a default value, the return value can also specify the type:

boolean isMan = environment.getProperty("author.isMan", Boolean.class, true);
System.out.println("author.isMan:" + isMan);

Output:

author.isMan:true

1.1.2 Properties placeholder

Environment In addition to using external getting a property value, we can use to obtain the placeholder property.

Spring in the assembly, use placeholders in the form of "$ {...}" attribute name package.

New Book categories as follows:

package chapter03.el;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class Book {
    @Value("${book.name}")
    private String bookName;

    @Value("${book.author}")
    private String bookAuthor;

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public String getBookAuthor() {
        return bookAuthor;
    }

    public void setBookAuthor(String bookAuthor) {
        this.bookAuthor = bookAuthor;
    }
}

Can be found, we add in the field of @Value notes, the value of the parameter passed is the property placeholder for obtaining property values ​​specified in the file attribute.

Then, add the following code ExpressiveConfig configuration classes:

@Autowired
private Book book;

public void outputResource() {
     System.out.println("book.name:" + book.getBookName());
     System.out.println("book.author:" + book.getBookAuthor());
}

Output:

book.name:spring boot

book.author:wangyunfei

2. Spring Expression Language

Spring Expression Language (Spring Expression Language, SpEL) is a very flexible expression language, it can be a powerful and simple way to assemble bean property value or constructor parameter, used in the process of expression calculates the value at runtime.

SpEL expression to put "# {...}" among previously mentioned properties and placeholder is put "$ {...}" at home.

Next, we use sub-scenes look at the Spring expression language.

Reference system property value 2.1

Add the following code in ExpressiveConfig:

@Value("#{systemProperties['os.name']}")
private String osName;

public void outputResource() {
    System.out.println("os.name:" + osName);
}

Output:

os.name:Windows 7

2.2 reference bean properties and methods

First, a new class DemoService follows:

package chapter03.el;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class DemoService {
    @Value("DemoService类的another属性")
    private String another;

    public String getAnother() {
        return another;
    }

    public void setAnother(String another) {
        this.another = another;
    }
}

Then, add the following code in ExpressiveConfig:

@Value("#{demoService.another}")
private String fromAnother;

public void outputResource() {
    System.out.println("demoService.another:" + fromAnother);
}

Expression demoService is DemoService bean's ID, another is its property.

Output:

demoService.another: another attribute class DemoService

The expression can also be modified to call the bean method:

@Value("#{demoService.getAnother()}")
private String fromAnother;

The output unchanged, but turned into a method call from the call attributes.

After calling the method, the return value of the method can continue to invoke other methods, such as toUpperCase ():

@Value("#{demoService.getAnother()?.toUpperCase()}")
private String fromAnother;

The reason for using "?." Operator, in order to avoid when demoService.getAnother()return null, code appears NullPointerException.

At this time, the output is:

demoService.another: ANOTHER class attribute DEMOSERVICE

Type used in expressions 2.3

Expression generated using a random number:

@Value("#{T(java.lang.Math).random()}")
private double randomNumber;

public void outputResource() {
    System.out.println("randomNumber:" + randomNumber);
}

Here we use T () cited java.lang.Math class, and then call its static method random ().

Output:

randomNumber:0.6801944394506442

2.4 operator

In the above example, after generating a random number, we can use the multiplication operator, as follows:

@Value("#{T(java.lang.Math).random() * 100.0}")
private double randomNumber;

We can also be used in the expression "+" string concatenation operator, as follows:

@Value("#{book.getBookName() + ' write by ' + book.getBookAuthor()}")
private String bookDescr;

public void outputResource() {
    System.out.println("bookDescr:" + bookDescr);
}

Wherein the book is ID, the output for the Book bean follows:

bookDescr:spring boot write by wangyunfei

Ternary operator may also be used in the expression:

@Value("#{systemProperties['os.name'] == 'Windows 7'?'Windows':'Linux'}")
private String osType;

public void outputResource() {
    System.out.println("osType:" + osType);
}

Because my computer system is Windows 7, so the output results are as follows:

osType:Windows

SpEL also supports many operators, just to name a few common example, interested students can study at their own depth.

3. Source and reference

Source Address: https://github.com/zwwhnly/spring-action.git , welcome to download.

Craig Walls "Spring combat (4th Edition)"

Wang Yunfei "Java EE developers insurgents: Spring Boot real"

Resource files under the IDEA maven project src source code is not automatically copied to the solution classes folder

The original is not easy, if that article can learn something, like a welcome point, a commentary on, off a note, this is my greatest motivation insist on writing.

If you are interested, please add my micro letter: zwwhnly , waiting for you to talk technology, workplace, work and other topics (PS: I am a programmer struggle in Shanghai).

Published 34 original articles · won praise 107 · views 20000 +

Guess you like

Origin blog.csdn.net/zwwhnly/article/details/100915437