简体   繁体   中英

Spring @Value field is null

I have problem with @Value annotation in Spring, i'm trying set field from properties file. My configuration applicationContext.xml is

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="ignoreUnresolvablePlaceholders" value="true" />
    <property name="locations">
        <list>
            <value>classpath:config/local/*.properties</value>
        </list>
    </property>
</bean>

properties file is in src/main/resources/config/local/general.properties

General properties

general.key="EDC183ADVARTT"

And in my class i want to inject field from this file. My class

import java.security.Key;

import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec;
import javax.persistence.AttributeConverter;

import org.postgresql.util.Base64; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.stereotype.Component;

@javax.persistence.Converter 
@Component 
public class EntityEncryptionConverter implements AttributeConverter<String, String> {

    @Value("${general.key}")
    private String keyCode;

    private static final String ALGORITHM = "AES/ECB/PKCS5Padding";
    private static final byte[] KEY = "395DEADE4D23DD92".getBytes();

    public String convertToDatabaseColumn(String ccNumber) {
        System.out.print(keyCode);
        // do some encryption
        Key key = new SecretKeySpec(KEY, "AES");
        try {
            Cipher c = Cipher.getInstance(ALGORITHM);
            c.init(Cipher.ENCRYPT_MODE, key);
            return Base64.encodeBytes(c.doFinal(ccNumber.getBytes()));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public String convertToEntityAttribute(String dbData) {
        // do some decryption
        Key key = new SecretKeySpec(KEY, "AES");
        try {
            Cipher c = Cipher.getInstance(ALGORITHM);
            c.init(Cipher.DECRYPT_MODE, key);
            return new String(c.doFinal(Base64.decode(dbData)));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

Why my value of KeyCode is null ?

This:

<value>classpath:config/local/*.properties</value>

should be:

 <value>classpath:*.properties</value>

There was a typo on the Value with an extra '

@Value("{general.key'}")

Should be:

@Value("{general.key}")

Is the EntityEncryptionConverter bean in the same Spring context as the PropertyPlaceholderConfigurer? Post processors only decorate beans in the same context.

Edit

As we discussed, the EntityEncryptionConverter instance you're getting in JPA is not the Spring managed instance created by Spring's component scan. Thus, no value set on keyCode.

I think you have a few choices here, none of which I find very "clean".

  1. Don't use Spring to get keyCode value in the Converter. In the Converter, read the keyCode value from a properties file old school via Java Properties.

  2. You want to use Spring, ok... Then create an Application Context aware Converter. You could create an AppContext provider as described here . With that provider you could either look up the keyCode in Spring (may have to expose it as a String bean) or you could look up the EntityEncryptionConverter instance that Spring is managing, then delegate the converter methods to that instance.

请尝试以下操作:

@Value("#{general['general.key']}")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM