如何在实现Condition/ConfigurationCondition接口的类中使用@Value或Environment

Man*_*dan 1 spring spring-3 spring-java-config spring-4

我只使用JavaConfig.

我有以下声明:

@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
    return new PropertySourcesPlaceholderConfigurer();
}
Run Code Online (Sandbox Code Playgroud)

根据以下帖子,JavaConfig是必需的: 使用纯Java配置的Spring 3.2 @value注释不起作用,但Environment.getProperty可以正常工作

以下代码完美(许多@Values通过测试目的):

@Configuration
public class ActiveMQServerConfiguration {

    @Value("${localhost.address}")
    private String localHost;

    @Value("${remotehost.address}")
    private String remoteHost;

    @Value("${localhost.port}")
    private Integer localPort;

    @Value("${remotehost.port}")
    private Integer remotePort;

    @Bean(name="connectionFactory")
    @Conditional(LocalHostStatusCondition.class)
    public ActiveMQConnectionFactory localConnectionFactory(
            @Value("${localhost.protocol}") String protocol,
            @Value("${localhost.address}") String host,
            @Value("${localhost.port}") String port ){

        System.out.println("protocol: "+protocol);
        System.out.println("host: "+host);
        System.out.println("port: "+port);

        System.out.println("localHost: "+localHost);
        System.out.println("localPort: "+localPort);
        System.out.println("remoteHost: "+remoteHost);
        System.out.println("remotePort: "+remotePort);
Run Code Online (Sandbox Code Playgroud)

我可以在控制台/终端中看到

Α

protocol: tcp
host: 127.0.0.1
port: 61616
localHost: 127.0.0.1
localPort: 61616
remoteHost: 192.168.1.34
remotePort: 61616
Run Code Online (Sandbox Code Playgroud)

但以下不符合预期:

public class LocalHostStatusCondition implements Condition {

    private static final Logger logger = LoggerFactory.getLogger(LocalHostStatusCondition.class);

    @Value("${localhost.address}")
    private String localHost;

    @Value("${remotehost.address}")
    private String remoteHost;

    @Value("${localhost.port}")
    private Integer localPort;

    @Value("${remotehost.port}")
    private Integer remotePort;

    @Autowired
    private Environment environment;

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        logger.info("LocalHostStatusCondition...");

        System.out.println("localHost: "+localHost);
        System.out.println("localPort: "+localPort);
        System.out.println("remoteHost: "+remoteHost);
        System.out.println("remotePort: "+remotePort);
        System.out.println("Env..." + environment.getProperty("localhost.address", String.class) );
Run Code Online (Sandbox Code Playgroud)

几乎一样,甚至与环境合作

输出是:

Beta版

localHost: null
localPort: null
remoteHost: null
remotePort: null
[WARNING] 
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
    at com.manuel.jordan.infrastructure.support.LocalHostStatusCondition.matches(LocalHostStatusCondition.java:42)
Run Code Online (Sandbox Code Playgroud)

根据条件API:

条件必须遵循与BeanFactoryPostProcessor相同的限制,并注意永远不要与bean实例交互.要更好地控制与@Configuration bean交互的条件,请考虑ConfigurationCondition接口.

关于ConfigurationCondition我已经读过这个什么时候使用Spring @ConfigurationCondition vs. @Condition?

我编辑了以下内容:

public class LocalHostStatusCondition implements ConfigurationCondition {

…

    @Override
    public ConfigurationPhase getConfigurationPhase() {
        return ConfigurationPhase.PARSE_CONFIGURATION;
    }
Run Code Online (Sandbox Code Playgroud)

如果我使用:

  • ConfigurationPhase.REGISTER_BEAN我得到的Beta输出相同
  • ConfigurationPhase.PARSE_CONFIGURATION; 我没有错,但......

但控制台/终端没有显示任何关于句子工作,我的意思是,System.out不打印(我不明白这种奇怪的行为).

我怎么解决这个问题?

我需要工作@Value或Environment,它的目的是让我们知道应用程序是否应连接到本地或远程ActiveMQ服务器.

是的,我已阅读以下内容: 如何延迟评估Spring @Conditional配置注释? 似乎没有解决方案......

谢谢

Sot*_*lis 5

你有

@Conditional(LocalHostStatusCondition.class)
Run Code Online (Sandbox Code Playgroud)

Spring采用Class您指定的类型并将其实例化以使用其matches方法.它不会将实例视为bean,也不会对其执行自动装配,也不会对其进行任何@Value处理.后者也是如此BeanFactoryPostProcessor.

你可以检索EnvironmentConditionContext,如果你想.另一种方法是自己加载属性.