2012-09-21 102 views
22

我有一個具有靜態方法的Util類。在我的Util類中,我想使用spring bean,所以我將它們包含在我的util類中。 據我所知,使用spring bean作爲靜態字段並不是一個好習慣。 但有沒有什麼辦法可以在靜態方法中訪問spring bean?以靜態方法訪問spring beans

我的例子:

public class TestUtils { 

    private static TestBean testBean; 

    public void setTestBean(TestBean testBean) { 
    TestUtils.testBean = testBean; 
    } 

    public static String getBeanDetails() { 
    return beanName = testBean.getDetails(); 
    } 
} 

我看到在許多論壇,這是不是最好的做法。有人能告訴我我該如何處理這種情況?

我的配置文件:

<bean id="testUtils" class="com.test.TestUtils"> 
<property name="testBean" ref="testBean" /> 
</bean> 

回答

0

你介紹的方法是我所看到的被用於一個Spring bean注入到一個實用程序類。

<bean id="testUtils" class="com.test.TestUtils"> 
<property name="testBean" ref="testBean" /> 
</bean> 

另一種選擇是:

<bean name="methodInvokingFactoryBean" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> 
     <property name="staticMethod" value="TestUtils.setInstance"/> 
     <property name="arguments"> 
      <list> 
       <ref bean="testBean"/> 
      </list> 
     </property> 
</bean> 

有:

public class TestUtils { 

    private static testBean; 

    public static void setInstance(TestBean anInstance) { 
    testBean = anInstance; 
    } 

    public static String getBeanDetails() { 
    return testBean.getDetails(); 
    } 
} 

更多細節herehere

+0

我不清楚..你能PLZ添加中,testBean配置? – TechSpellBound

1

這是我從春天注射靜態字段。

<bean id="..." class="..."> 
<property name="fieldToBeInjected"> 
      <util:constant static-field="CONSTANT_FIELD" /> 
     </property> 
</bean> 

也許這會幫助你,爲好。

10

靜態方法的結果應該只取決於傳遞給方法的參數,因此不需要調用任何bean。

如果您需要調用另一個bean,那麼您的方法應該是獨立bean的成員方法。

其他答案給你工作的解決方案,但它可以做的事實並不意味着它應該完成。

+0

是的,我認爲我們應該將它用作參數,而不是直接在靜態類中進行設置。根據標準,它表示我們不應該使用這個bean作爲靜態,儘管我們可以用不同的方式來實現,如上面的響應所示。謝謝回覆。 – Rosh

+1

「靜態方法的結果應該只取決於傳遞給方法的參數」,好的鏡頭! – Nickolas

9

你也可以實現ApplicationContextAware接口,就像這樣:

@Component 
public class TestUtils implements ApplicationContextAware { 

    private static ApplicationContext ac; 

    public static String getBeanDetails() { 
    return beanName = ((TestBean) ac.getBean("testBean")).getDetails(); 
    } 

    @Override 
    public void setApplicationContext(ApplicationContext ac) { 
    this.ac = ac; 
    } 

} 
29

我的做法是一個希望訪問來實現InitializingBean或使用@PostConstruct豆,和包含靜態引用到自身。

例如:在靜態類

@Service 
public class MyBean implements InitializingBean { 
    private static MyBean instance; 

    @Override 
    public void afterPropertiesSet() throws Exception { 
     instance = this; 
    } 

    public static MyBean get() { 
     return instance; 
    } 
} 

用法將因此僅僅是:

MyBean myBean = MyBean.get(); 

這種方式,不需要XML配置,你並不需要通過在豆作爲構造函數的參數,並且調用者不需要知道或關心bean是使用Spring進行連接的(即不需要混亂的ApplicationContext變量)。

+0

浮油 - 是否有一個很好的地方,找到正確的解決方法,在春季這種反覆出現的問題..? –

1

與@ nullPainter的回覆類似,但我們做了以下操作。不需要構建後的邏輯。它只是在注入過程中直接設置靜態成員(在@Autowired方法中)。

@Service 
public class MyUtil { 

    private static MyManager myManager; 

    @Autowired(required = true) 
    public void setMyManager(MyManager manager) { 
     myManager = manager; 
    } 

    public static MyManager getMyManager() { 
     return myManager; 
    } 
} 
+0

不需要傳遞'required = true'參數,因爲這是'@ Autowired'的默認值。所以只有 '@Autowired public void setMyManager(MyManager manager){ myManager = manager; }' 就足夠了。 – rumman0786

+0

需要@Service註釋,這沒有什麼意義 – rohanagarwal

0

這對我的作品。在一些類:

import org.springframework.web.context.ContextLoader; 
import org.springframework.web.context.WebApplicationContext; 

WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext(); 
DataSource datasource = (DataSource)context.getBean("dataSourceDB_01");  

在我的xml配置:

<bean id="dataSourceDB_01" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName"><value>${db.driver}</value></property>  
    <property name="url"><value>${db.url}</value></property> 
    <property name="username"><value>${db.username_seg}</value></property> 
    <property name="password"><value>${db.password_seg}</value></property> 
</bean> 

HTH