【问题标题】:Spring Injection - InstancesSpring 注入 - 实例
【发布时间】:2015-12-15 23:58:42
【问题描述】:

我是 Spring 新手,但我无法弄清楚这一点。 当我两次或多次调用myMethod 时,myManager 中的propA 会被覆盖,并且每次都为相同的propA 值(最后设置)调用“doSomething”。 Spring注入是如何工作的?每次调用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
    }
}
}

弹簧配置:

<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);
 }
}
}

【问题讨论】:

  • 你可以使用注解吗?
  • 你如何获得“myClass”bean?通过 applicationcontext.getbean ?你可以访问应用程序上下文吗?

标签: java spring spring-mvc code-injection


【解决方案1】:

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

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

public class MyManagerfactory {

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

}

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

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

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

希望对你有帮助,

阿图尔

【讨论】:

  • 我现在无法尝试,但是我的create() 方法应该怎么做?类似'return new MyManager();'在这种情况下,注射在哪里进行?
  • create 方法将创建 MyManager 类的新实例。可能只是调用构造函数,不确定,无论您的对象需要什么。这个想法是你希望每次调用工厂创建一个新实例时都有一个新实例。
  • 您不能在创建时间之后执行注入,如回答中所述。只有在 MyClass 中注入 MyManagerFactory 时才会执行注入。
  • 是的,这意味着 managerFactory 实现无法解决我的问题。我说的对吗?
  • 它将解决您的问题。通过插入工厂,工厂将为每次调用创建新的管理器。所以每个经理都会有自己的propA,不会互相覆盖。
猜你喜欢
  • 1970-01-01
  • 2011-12-05
  • 2012-02-26
  • 2016-07-06
  • 1970-01-01
  • 2011-01-06
  • 1970-01-01
  • 2015-08-05
  • 2012-05-02
相关资源
最近更新 更多