Use @ Value value injection and profile component scanning

  • 2021-10-25 06:42:10
  • OfStack

@ Value Value Injection and Profile Component Scanning

The spring configuration file corresponds to the parent container, and the springMVC configuration file generates the child container. The former configures data sources, transactions, annotations, etc. Of course, one step can be taken to refine some configurations to other xml; The latter 1 generally configures control layer related, such as static resources, view parser and so on.

When the system starts, initialize the parent container first, and then initialize the child container. There is a problem involved here. If you configure the full component scan when configuring the component scan, the service component will be scanned twice, resulting in the transaction being unable to be processed.

Therefore, it is best to scan only controller in springMVC configuration file and scan other components in spring configuration file.

Configure in the configuration file of spring:


<context:component-scan base-package="com"/>

Configure in the configuration file of springMVC:


<context:component-scan base-package="com.**.controller"/>

In this way, we can perform our duties.

In use, these two profiles have different functions. Note if you want to use @ Value to inject 1 variable in the system configuration file: If you want to use injected variables in controller, you need to configure in the configuration file of springMVC:


<context:property-placeholder location="classpath:{your variable file}.properties"/>

If it is configured only in the configuration file of spring, it will not be injected successfully in controller. The reason is that when the project starts, the parent container is initialized first, and then the child container is initialized. If both scanned the same component at initialization, the child container overwrites the parent container's associated bean. The child container overwrites the original value with null because it does not have the file bean to configure the environment variables (the child container can see the parent container's bean, but not the other way around).

Test the demo as follows:


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml",
"classpath:servlet-dispatcher.xml"})
public class InjecTest {
    @Value("${ly.key}")
    private String key;
    @Test
    public void test(){
        System.out.println(" Injecting key Is: "+key);
    }

There are two ways to inject based on @ Value, placeholders and spel expressions


 // Placeholder mode 
    @Value("${jdbc.url}")
    private String url;

 //SpEL Expression, which represents xml In the configuration file id Value configProperties
    @Value("#{configProperties['jdbc.username']}")
    private String userName;

These two methods need to be configured in xml, and they are not the same


<!-- Placeholder-based approach   Configure a single properties -->
    <!--<context:property-placeholder location="conf/jdbc.properties"/>-->
    <!-- Placeholder-based approach   Configure multiple properties -->
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:config/resource/dev/application.properties</value>
                <value>classpath:config/resource/dev/lyframework.properties</value>
                <value>classpath:config/resource/dev/common.properties</value>
            </list>
      </property>
    </bean>

 <!-- Based on SpEL Expression   Configure multiple properties id Value is configProperties  Provide java Use in the code  -->
    <bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="locations">
            <list>
                <value>classpath:/conf/jdbc.properties</value>
            </list>
        </property>
    </bean>
    <!-- Based on SpEL Expression   Configure a single properties -->
    <!--<util:properties id="configProperties" location="classpath:conf/jdbc.properties"/>-->

Spring @ Value could not get a value

1. Background of the problem

When doing things in the past two days, I found a problem. When using @ Value in SpringMVC, I couldn't get the corresponding value of @ Value. After consulting all kinds of materials on the Internet, summarize 1.

2. The role of @ Value annotations

In order to reduce coupling, a few fixed constants are usually placed in the configuration file ***. properties.

properties Content Definition Form: Name = Value


SAY_COUNT=10
TITLE_COUNT=10
MESSAGE_COUNT=10
BACK_COUNT=10

When these constants are needed, use them where they are needed by loading the properties file. When you need to modify these constant values, you only need to modify them in the configuration file.

Before using spring, you had to write code manually to load the configuration file if you wanted to use the data in the configuration file. But with spring, this can be done by adding a configuration to spring.


<context:property-placeholder location="classpath:resource/resource.properties"/>

Injection can be done automatically by using @ Value annotations where needed.


<context:component-scan base-package="com.**.controller"/>
0

3. Failure to get a value

1) When SpringMVC is integrated with Spring, the value of @ Value cannot be obtained in Controller. (This was the case with me at first.)

Cause: Scanning was added only in applicationContext, not in the configuration file corresponding to SpringMVC.

applicationContext loads the parent container, which is loaded when the project starts. The configuration file corresponding to SpringMVC loads a child container, which can access the objects of the parent container, but cannot access the loaded configuration file. Therefore, if you want to use the loaded configuration file in SpringMVC, you need to add the corresponding configuration in the corresponding configuration file of SpringMVC.

2) The @ Value value cannot be obtained at the service or dao layer.

Possibility: There are multiple applicationContext. xml files with multiple context: property-placeholder. When the web container is started, these configuration files are loaded at the same time. At this time, only one configuration file with context: property-placeholder will be loaded, and the others will not be loaded.

So, when you need to load multiple properties, how to solve it? You can use the following methods


<context:component-scan base-package="com.**.controller"/>
1

In this way, put all the properties that need to be loaded under one directory, and all properties files can be loaded through *. properties.


Related articles: