【问题标题】:How to use @Value on Spring non-managed class如何在 Spring 非托管类上使用 @Value
【发布时间】:2017-05-04 08:59:15
【问题描述】:

在解释我的问题之前,这里是我的(简化的)代码:

foo.bar.MyFile

public class MyFile extends MyFileAbstract {

    @Value("${FILE_PATH}")
    private String path;

    [...]
    
    public MyFile(final Date date, final String number, final List<MyElement> elements) {
        this.date = date;
        this.number = number;
        this.elements = elements;
    }
    
    @Override
    public String getPath() {
        return path;
    }
    
    [...]
}

foo.bar.MyService

@Service
public class MyService {

    [...]
    
    public String createFolder(MyFileAbstract file) throws TechnicalException {
        
        [...]
        
        String path = file.getPath();
        
        [...]
    }
    
    [...]
}

服务的召唤

[...]
@Autowired
MyService service;

public void MyMethod() {
    MyFile file = new MyFile();
    service.createFolder(file);
    [...]
}

[...]

我使用上下文 XML 来配置 Spring:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/util 
        http://www.springframework.org/schema/util/spring-util.xsd">

    <context:property-placeholder
        file-encoding="utf-8"
        location="file:///[...]/MyProperties.properties" />

    <context:annotation-config />   
 
    <context:component-scan base-package="foo.bar.classes" />
    
    [...]
</beans>

问题是当实例化MyFile 调用我的服务MyService 时,MyServiceMyFile 文件中的变量path 在运行时为空。

我正在寻找一种解决方案,将我的属性 ${FILE_PATH} 注入到 MyFile 中。

这里是我的环境:

  • Apache Tomcat 7
  • Java 8
  • Spring 4.1.6.RELEASE

我已经看到带有 @Configurable bean 的 Spring AOP 可以解决这个问题,但我不想更改我的 Java 代理,因为我不想修改生产服务器上的配置。

而且我不知道如何将@Service on MyFile 与我的自定义构造函数一起使用。

欢迎提出任何想法。

【问题讨论】:

    标签: java spring tomcat code-injection


    【解决方案1】:

    您可以添加到您的 MyService

    @Autowired
    private Environment environment;
    

    然后获取价值

    environment.getProperty("FILE_PATH");
    

    之后,您可以根据需要将其设置为文件。

    【讨论】:

    • 是的,可以作为解决方案。我可以在我的服务中使用 Value 而不是 Autowired。不是真的“干净”,但这是一个解决方案......
    【解决方案2】:
     @Service
     public class BeanUtilityService implements ApplicationContextAware {
    
       @Autowired
       private static ApplicationContext context;
    
       @Override
       public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
       }
    
       public static <T> T getBean(Class<T> beanClass) {
        return context.getBean(beanClass);
       }
    }
    

    创建一个实用程序类作为服务,创建一个静态方法并从上下文中获取 bean。然后使用该 bean 获取所需的属性

    【讨论】:

      【解决方案3】:

      使用@PropertySource 注解

      @PropertySource("classpath:config.properties") //use your property file name
      public class MyFile extends MyFileAbstract {
      
          @Value("${FILE_PATH}")
          private String path;
      
          [...]
      
          public MyFile(final Date date, final String number, final List<MyElement> elements) {
              this.date = date;
              this.number = number;
              this.elements = elements;
          }
      
          @Override
          public String getPath() {
              return path;
          }
      
          [...]
      }
      

      【讨论】:

      • 这无济于事,因为 MyFile 不是 bean 而是手动创建的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 2019-07-14
      • 1970-01-01
      • 1970-01-01
      • 2018-03-19
      • 2011-09-18
      相关资源
      最近更新 更多