About the injection data description
1. Do not inject data through the configuration file
Using @value to dynamically inject an external Value into the Bean:
- Injecting a normal string
- Inject operating system properties
- Injection expression result
- Inject other Bean properties: Inject the name property of the Student object
- Injecting file Resources
- Injecting URL Resources
The auxiliary code
package com.hannpang.model;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component(value = "st")// Instantiate student
public class Student {
@Value("The wu is empty")
private String name;
public String getName(a) {
return name;
}
public void setName(String name) {
this.name = name; }}Copy the code
Test the code for @value
package com.hannpang.model;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
@Component
public class SimpleObject {
@Value("Inject a normal string")
private String normal;
// For the KEY of the attribute, see the System class description
@Value("#{systemProperties['java.version']}")//--> use the SpEL expression
private String systemPropertiesName; // Inject the operating system properties
@Value("#{T(java.lang.Math).random()*80}")// Get a random number
private double randomNumber; // Inject the result of the expression
@Value("# {1 + 2}")
private double sum; // Insert the sum of 1+2 resulting from the expression
@Value("classpath:os.yaml")
private Resource resourceFile; // Inject file resources
@Value("http://www.baidu.com")
private Resource testUrl; // Inject URL resources
@Value("#{st.name}")
private String studentName;
// Omit the getter and setter methods
@Override
public String toString(a) {
return "SimpleObject{" +
"normal='" + normal + '\' ' +
", systemPropertiesName='" + systemPropertiesName + '\' ' +
", randomNumber=" + randomNumber +
", sum=" + sum +
", resourceFile=" + resourceFile +
", testUrl=" + testUrl +
", studentName='" + studentName + '\' ' +
'} '; }}Copy the code
Spring test code
package com.hannpang;
import com.hannpang.model.SimpleObject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class Demo04BootApplicationTests {
@Autowired
private SimpleObject so;
@Test
public void contextLoads(a) { System.out.println(so); }}Copy the code
The running result is: SimpleObject{normal=' 1.8.0_172', systemPropertiesName='1.8.0_172', randomNumber=56.631954541947266, sum=3.0, ResourceFile =class path resource [os.yaml], testUrl=URL [http://www.baidu.com], studentName=' Wukong '}Copy the code
2. Inject data through the configuration file
The Value of the external configuration file is dynamically injected into the Bean via @value. There are two main types of configuration files:
- Properties, application.yaml application.properties this file is loaded by default when Spring Boot is started
- Custom properties file. Custom properties files are loaded via @propertysource. @propertysource can load multiple files at the same time or a single file. If the first property file and the second property file have the same key, then the key in the last property file is enabled. The path to the load file can also be configured as ${anotherfile.configinject}, which is defined in the first property file config.properties
-
Add the following test code to application.properties
App. name= Step educationCopy the code
-
Create the first properties file, config.properties, under Resources, as follows
Book. name= Journey to the West anotherFile. configinject=systemCopy the code
-
Create a second properties file, config_System.properties, under Resources as follows
My goal is to use the values defined in the first properties file for the system value
The book. The name. The author = wu chengenCopy the code
@value (${app.name}) @value (${app.name}) @value (${app.name}) @value (${app.name}) @value (${app.name}) @value (${app.name})
package com.hannpang.test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
@Component
@PropertySource(value = {"classpath:config.properties"."classpath:config_${anotherfile.configinject}.properties"})
public class LoadPropsTest {
@Value("${app.name}")
private String appName; // The value here is from application.properties, which is loaded by default when Spring Boot starts
@Value("${book.name}")
private String bookName; // Inject the first configuration external file properties
@Value("${book.name.author}")
private String author; // Inject the second configuration external file properties
@Autowired
private Environment env; // Inject an environment variable object to store the values of the injected properties
// Omit the getter and setter methods
public void setAuthor(String author) {
this.author = author;
}
@Override
public String toString(a){
StringBuilder sb = new StringBuilder();
sb.append("bookName=").append(bookName).append("\r\n")
.append("author=").append(author).append("\r\n")
.append("appName=").append(appName).append("\r\n")
.append("env=").append(env).append("\r\n")
// Get the attribute value from eniroment
.append("env=").append(env.getProperty("book.name.author")).append("\r\n");
returnsb.toString(); }}Copy the code
The test code
package com.hannpang;
import com.hannpang.model.SimpleObject;
import com.hannpang.test.LoadPropsTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class Demo04BootApplicationTests {
@Autowired
private LoadPropsTest lpt;
@Test
public void loadPropertiesTest(a) { System.out.println(lpt); }}Copy the code
The running result is: Env =StandardEnvironment {activeProfiles=[], defaultProfiles=[default], propertySources=[ConfigurationPropertySourcesPropertySource {name='configurationProperties'}, MapPropertySource {name='Inlined Test Properties'}, MapPropertySource {name='systemProperties'}, OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}, RandomValuePropertySource {name='random'}, OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.properties]'}, ResourcePropertySource {name='class path resource [config_system.properties]'}, ResourcePropertySource {name='class path resource [config.properties]'}]} env= Wu Cheng 'enCopy the code
3. # {... } and ${... }
Demonstration of the difference between
A.The ${... }
The use of the
@value (” ${app.name} “);} {app.name}; You can solve this problem by giving default values, such as @value (“${app.name: chubbyson}”).
Part of the code
// If the properties file does not have app.name, an error will be reported
// @Value("${app.name}")
// private String name;
// Use app.name to set the value, or the default value if it does not exist
@Value("${app.name: name}")
private String name;
Copy the code
B.# {... }
The use of the
Part of the code directly demonstrated
// SpEL: calls the concat method of the string Hello World
@Value("#{'Hello World'.concat('! ')}")
private String helloWorld;
// SpEL: Call the getBytes method of the string, and then call the length attribute
@Value("#{'Hello World'.bytes.length}")
private String helloWorldbytes;
Copy the code
C.# {... }
andThe ${... }
A mixture of
The ${… #} and {… ${server.name} gets the value from the properties file and replaces it, which then becomes executing the SpEL expression {‘ server1,server2,server3 ‘.split(‘, ‘)}.
// SpEL: pass in a string (${}, ${}, ${}, ${}, ${}, ${});
@Value("#{'${server.name}'.split(',')}")
private List<String> servers;
Copy the code
${} on the outside, #{} on the inside. ${} on the inside
// SpEL: if ${} is on the outside and #{} is on the inside, this will fail
@Value("${#{'HelloWorld'.concat('_')}}")
private List<String> servers2;
Copy the code
The answer is no. Spring executes ${} earlier than #{}. In this case, Spring will try to find #{' HelloWorld '.concat(' _ ')} from the property, so it will definitely find it, and as we know above if it can't find it, then it will report an error. So ${} on the outside, #{} on the inside is illegalCopy the code
[D]
- # {… } is used to execute the SpEl expression and assign the content to the property
- The ${… } is used to load values from external properties files
- # {… } and ${… } can be mixed, but it must be #{} outside and ${} inside
4.@Value gets the value compared to @configurationProperties
@ConfigurationProperties | @Value | |
---|---|---|
function | Batch injection of properties in the configuration file | Specify one by one |
Loose binding (loose syntax) | support | Does not support |
SpEL | Does not support | support |
JSR303 data verification | support | Does not support |
Complex type encapsulation | support | Does not support |
They can get values for both yML and properties;
-
If we just need to get the Value of an item in the configuration file in some business logic, use @value;
-
If we specifically wrote a Javabeans to map to a configuration file, we would use @ConfigurationProperties directly;
Part of the code for data verification
@Component
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {
//lastName must be in mailbox format
@Email
private String lastName;
Copy the code
5. @ImportResource
Importing a Configuration File
This is not recommended
There is no Spring configuration file in Spring Boot, and the configuration file written by us cannot be automatically identified.
To make the Spring configuration file work, load it in. The @ImportResource annotation is on a configuration class
@ImportResource(locations = {"classpath:beans.xml"}) Import Spring's configuration file to make it workCopy the code
Write configuration file information
<?xml version="1.0" encoding="UTF-8"? >
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="helloService" class="com.hanpang.springboot.service.HelloService"></bean>
</beans>
Copy the code
Just to get the idea, we don’t really use it
6.@Configuration
annotations
The way SpringBoot recommends adding components to a container; The full annotated approach is recommended
The @configuration class is applied to a class and acts as an XML Configuration file
Add a component to the container using @bean and apply it to the method
/ * * *@Configuration: indicates that the current class is a configuration class. <bean id="helloService" ><bean/> <bean/> class="com.hanpang.springboot.service.HelloService"></bean> */
@Configuration
public class MyAppConfig {
// Add the return value of the method to the container; The default ID for this component in the container is the method name
@Bean
public HelloService helloService02(a){
System.out.println("Config class @bean adds components to the container...");
return newHelloService(); }}Copy the code
Bean injection is too cumbersome, and we prefer to use scanning
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import com.wx.dao.IUserDao;
import com.wx.dao.UserDaoImpl;
// Use this annotation to indicate that the class is a Spring configuration, equivalent to a traditional ApplicationContext.xml
@Configuration
// Equivalent to the
tag in the configuration file, scan for the annotations of the classes below these packages
@ComponentScan(basePackages="com.hanpang.dao,com.hanpang.service")
public class SpringConfig {
// Use this annotation to indicate that it is a Bean object, equivalent to < Bean > in XML
// The default id value of the bean is the method name userDao
/* @bean public HelloService helloService02(){system.out.println (" @bean added component to container...") ); return new HelloService(); } * /
}
Copy the code
The appendix
The random number
The ${random value}, ${random.int}, ${random.long}
${random.int(10)}, ${random.int[1024.65536]}
Copy the code