gpt4 book ai didi

java - Spring 注入(inject) - 实例

转载 作者:行者123 更新时间:2023-12-01 10:43:59 25 4
gpt4 key购买 nike

我是 Spring 新手,但我不明白这一点。当我调用 myMethod 两次或多次时,myManager 中的 propA 会被覆盖,并且每次都会调用“doSomething”对于相同的 propA 值(最后设置的)。Spring注入(inject)是如何工作的?每次调用 myMethod() 时,我都希望有一个新的 MyManager 实例。难道是我的方法不对?

这是我的简化(也是错误的)代码:

public class myClass {

private MyManager manager;
//..setter and getter

public String myMethod() {
//somelogic

manager.setPropA("a");

Thread tt = new Thread(manager);
try {
tt.start();
} catch (IllegalThreadStateException e) {
log.error("Errore", e);
}
}
}

public class MyManager implements Runnable {

private MyService service;
private String propA;

//Setters and getters
@Override
public void run() {
try {
// sleep(30000);
service.doSomething(propA);
} catch (Exception ex) {
//ERROR
}
}
}

Spring 配置:

<bean id="myClass" class="..." scope="prototype" >
<property name="manager" ref="MyManager"/>
</bean>


<bean id="MyManager" class="" scope="prototype">
<property name="service" ref="MyService"/>
</bean>


<bean id="MyService" class="...">
<property name="myDao" ref="MyDao" />
</bean>

是的,我有@reos。

我最终得到了这个解决方案,但我不太高兴并更改了我的代码。

这是我不满意的解决方案,如果有人感兴趣的话:

public class MyManager implements ApplicationContextAware,  Runnable {

private MyService service;
private String propA;
private static ApplicationContext applicationContext;


public MyManager() {

}

public static ApplicationContext getApplicationContext() {
return applicationContext;
}

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


//Others getters and setters


@Override
public void run() {
try {
// sleep(30000);
service= (MyService)this.applicationContext.getBean("MyService");
service.doSomething(propA);
} catch (Exception ex) {
//ERROR
}
}

}


public class myClass {

private MyManager manager;
//..setter and getter

public String myMethod() {
//somelogic

MyManager manager = new MyManager();
manager.setPropA("propA");

manager.setPropA("a");

Thread tt = new Thread(manager);
try {
tt.start();
} catch (IllegalThreadStateException e) {
log.error("Errore", e);
}
}
}

最佳答案

这是行不通的。据我所知,Spring 仅在创建时注入(inject)您的代码。因此,当创建 myClass 时,它将找到对 myManager 的引用,然后也将创建该引用,以便可以注入(inject)它。因此,您的经理将始终属于同一个实例。

如果您想要一个新实例,我建议实现一个工厂。

public class MyManagerfactory {

public MyManager create() { ... // create new instance }

}

您现在可以将工厂注入(inject) MyClass,而不是直接注入(inject)管理器。然后,工厂将创建一个新的管理器实例,您可以配置该实例并将其传递给线程来执行。

如果您想通过 Spring 执行此操作,则必须创建 MyClass 实例的多个实例,并向它们传递 MyManager 的不同实例。调用方法不会为您执行注入(inject)。

您可以通过应用程序上下文手动创建 Bean,但这也不是最理想的解决方案。我认为在这种情况下你想要一个工厂。

希望有帮助,

阿图尔

关于java - Spring 注入(inject) - 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34301709/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com