2013-01-06 36 views
4

在一个Spring MVC Web应用程序“之前”设置系统属性,我有在配置文件中配置为豆:配置Spring将一个bean被初始化

<bean class="com.callback.CallbackService"/> 

在服务类,豆被初始化如下图所示:

@Autowired 
CallbackService service 

上面所示的CallbackService得到通过进行以下三个调用它的连接属性(这不能用于现在改变):

System.getProperty("user"); 
System.getProperty("password"); 
System.getProperty("connectionURL"); 

其中CallbackService的实例中声明的服务类通过从属性读取访问上述三个值文件,如下所示:

@Value("${user}") 
protected String userName; 

@Value("${password}") 
protected String password; 

@Value("${connection}") 
protected String connectionString; 

所有我需要设置的属性的CallbackService是设置系统属性(它们已经被初始化之后),如下所示:

System.setProperty("user", userName); 
System.setProperty("password", password); 
System.setProperty("connectionURL", connectionString); 

但是我有问题是其中对象正被初始化的顺序。这些属性正在初始化,但它看起来像在Spring已经从属性文件准备好之前System.setProperty调用发生了。

我已经尝试了几种解决方案,但似乎在从属性文件读取值并调用System.setProperty之前实例化了CallbackService对象。

属性文件最终被读取,因为我可以看到值,如果我从@Controller方法之一访问它们。问题在于属性被初始化并且CallbackService实例被初始化。

后几个小时google搜索,我尝试以下解决方案,但似乎没有任何的CallbackService实例

  1. 实施InitiazingBeanafterPropertiesSet()方法中设置系统属性初始化/实例化之前填充系统属性。
  2. 实施ApplicationListener并在onApplicationEvent()方法中设置系统属性。
  3. 为XML中的CallbackService bean定义设置lazy-init=true
  4. 设置系统属性,本文上述Set System Property With Spring Configuration File

4点似乎是我想要的,但我没有看到任何区别,当我添加了以下(含三个属性,我需要)我的背景文件。

<bean id="systemPrereqs" 
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> 
    <property name="targetObject" value="#{@systemProperties}" /> 
    <property name="targetMethod" value="putAll" /> 
    <property name="arguments"> 
     <!-- The new Properties --> 
     <util:properties> 
      <prop key="java.security.auth.login.config">/super/secret/jaas.conf</prop> 
     </util:properties> 
    </property> 
</bean> 

我怎样才能确保值从属性文件读取到System.setProperty调用执行前,然后才应该CallbackService实例被实例化?

感谢

+0

有很多的细节在这里,但这个问题不与问题/答案格式适合...问题在开始时没有明确说明。 –

回答

4

可以让CallbackServicedepend on另一个Bean初始化系统属性,例如

class SystemPropertiesInitializer { 

     SystemPropertiesInitializer(@Value("${user}") String userName, 
       @Value("${password}") String password, 
       @Value("${connection}" String connectionString) { 

      System.setProperty("user", userName); 
      System.setProperty("password", password); 
      System.setProperty("connectionURL", connectionString); 
     } 
} 

接下来,

<bean id="systemPropertiesInitializer" class="com.callback.SystemPropertiesInitializer"/> 
<bean class="com.callback.CallbackService" depends-on="systemPropertiesInitializer"/> 

或者,你可以使用@DependsOn注释:

@Component 
@DependsOn("systemPropertiesInitializer") 
class CallbackService { 
    // implementation omitted 
} 
+0

谢谢我现在正在尝试这个。如果SystemPropertiesInitializer没有无参数构造函数,它将如何实例化? – ziggy

+0

你是说如果它_does_有一个无参数构造函数(或根本没有构造函数)?只需使用'@ Value'注释分别初始化每个字段,然后就可以使用[@PostConstruct](http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html /beans.html#beans-postconstruct-and-predestroy-annotations)注释,然后调用'System.setProperties(...)'方法。 – matsev