为什么Autowired bean不会创建新实例但是从上下文加载?

时间:2015-03-20 11:50:39

标签: spring spring-integration spring-bean

我有简单的调度程序。

public class MailSendScheduler {

    @Autowired 
    MailCollector mailCollector;

    @Scheduled(cron = "0/10 * * * * *")
    public void call() throws Exception {
        log.info("Method executed " + new Date());

        taskExecutor.initialize();

        for (int i = 0; i < 15; i++) {
                mailCollector.setText(Integer.toString(i));
            taskExecutor.execute(mailCollector);
        }
    }   
}

我的配置如下:

<bean id="mailCollector" class="ge.ddrc.school.mails.MailCollector" scope="prototype" >
            <property name="mailSender" ref="mailSender" />
    </bean>

Mail Controller是 runnable 类,我在run()方法中记录整数。

@Component
public class MailCollector extends Thread {
  public void run(){ log.info() }
}

您认为结果如何?它应该是从0到14不是吗?但它看起来不是这样的:

2,2,4,5,14,14,14,14,14,14,14,14,14,14,14.

似乎mailController是Singleton。我认为它不是在创造新的豆子。 但是等待,如果我这样写:

ApplicationContext context = new ClassPathXmlApplicationContext("spring/mail-config.xml");

        for (int i = 0; i < 15; i++) {
            MailCollector  mailCollector=(MailCollector) context.getBean("mailCollector");
            mailCollector.setText(Integer.toString(i));
            taskExecutor.execute(mailCollector);
        }

输出如下:1,2,3,4,5,8,9,6,7,10,15,13,​​14,12,11。这也是正确的!为什么会这样?

1 个答案:

答案 0 :(得分:0)

这就是Spring原型范围的工作原理。

原型范围意味着每个引用都有自己的实例(每个@Autowired,每个context.getBean())。

您必须使用自定义作用域和作用域代理来为循环的每次迭代获取新实例。那是非常先进的东西。创建自己的工厂以获得每次迭代的新实例可能更容易。