2012-09-10 47 views
4

從第一天起,我總是會有一個問題,那就是我使用spring的時候。如果一個類有一個需要兩個參數的構造函數,但這兩個參數不是固定的,它們是根據輸入請求生成的,每次它們都不相同,但是我需要spring容器來管理類的實例,如何在spring中實現這個? 例如如何創建一個需要動態參數的對象

Class A{ 
    A(int x,int y){//omit} 
} 

但X和Y是不固定的,我們需要通過我們的程序來計算x和y,那麼我們可以爲創建實例,在普通的Java代碼,如下面

int x=calculate(request); 
    int y=calculate(request); 
    A a=new A(x,y); 

但是如何讓spring來管理A類的實例創建?

附加信息:爲什麼我需要A類由Spring管理,因爲A取決於其他一些由Spring管理的類。

+3

爲什麼你想春天來管理這些實例? A中是否有任何由spring-container管理的成員? – Vikdor

+0

是的,我忘記指出A類依賴於由spring容器管理的其他一些類。 – Neo

回答

7
  • 最直接的方式做它使用ApplicationContext.getBean(String name, Object... args) - 它可以創建一個prototype放大的bean,將給定的參數傳遞給它的構造函數。顯然,在任何使用A的bean中直接使用ApplicationContext並不是一個好主意。

  • 一個更優雅的方法是隱藏在工廠後面創建A。該工廠可以在內部使用先前的方法,也可以通過常規方式獲得bean的實例(Provider<A>等),然後調用非初始化方法來傳遞該參數(而不是使用構造函數傳遞參數)。

  • 還有一個應用是使用@Configurable and load-time weaving,它允許Spring初始化用new創建的對象。雖然它需要一些額外的運行時環境配置。

+0

這真是個好主意,非常感謝 – Neo

2

它們是根據輸入請求生成的,每次它們都不一樣,但是我需要spring容器來管理類的實例,春天如何實現這個呢?

你不知道。您需要實例化以響應用戶輸入的類並不是由Spring管理的。

僅僅因爲你使用Spring來管理一些bean,並不意味着所有的bean /類都應該由Spring來管理。

+1

不同意。海報問如何使用Spring,而不是他是否應該使用Spring。 Spring的'scope =「request」'屬性支持每個用戶請求bean。 – noahlz

+0

@noahz是正確的,我需要所有的bean都由spring來管理,因爲有依賴關係需要由spring來管理,而且我認爲如果我們使用spring,但仍然使用new,我認爲這不是個好主意 – Neo

+0

I認爲第一點是公平的,但第二個陳述「如果我們使用春天,但仍然使用新的,我不認爲這是好主意」似乎是一個危險的想法。 –

0

也許你到構造改變爲:

Class A{ 
A(Request request){ this.x=calculate(request); ....} 
} 
0

我認爲int是一些Object instance.One方式更換,以實現這一目標是使用Spring's FactoryBean功能自定義bean的初始化:

class AFactory implements o.s.b.f.FactoryBean { 

    private SomeObject firstParam; 
    private OtherObject secondParam; 

    public Object getObject() { 
    return new A(firstParam, secondParam); 
    } 

    public Class getObjectType() { 
    return A.class; 
    } 

    public boolean isSingleton() { 
    return false; 
    // i.e. every time #getObject() is called a new instance is created === prototype scope 
    } 

    public void setFirstParam(SomeObject firstParam){} 
    public void setSecondParam(OtherObject secondParam){} 

} 

注意,如果SomeObjectOtherObject可實際上其他FactorBean s是A的依賴關係的工廠,那麼每次調用AFactory#getObject()時,實際上都會收到一個新實例A,該實例使用其所需依賴項的新實例。

0

你可以嘗試在Bean工廠類(由ApplicationContext的擴展),使用此方法

對象的getBean(字符串名稱,對象參數... args)拋出BeansException;

你的情況: context.getBean(「A」,x,y);

,其中 「A」 是bean的名字爲A級。

1

您希望您的Spring bean被定義爲prototype而不是singleton。這樣,在每個新的請求中,Spring上下文將創建一個新的bean實例。

在Java配置,它會是這個樣子:

@Scope("prototype") @Bean public MyBean myBean() { ... }

在XML:

<bean id="myBean" class="whatever.MyBean" scope="prototype"> ...

也有可連接到HTTP會話範圍。請參閱:

http://static.springsource.org/spring/docs/3.0.0.M3/reference/html/ch04s04.html

而且,正如其他人指出的那樣,你必須定義你的bean工廠方法:

參見:Spring and passing parameters to factory-method in runtime

相關問題