Spring在方法调用期间获取托管bean

时间:2014-09-28 12:52:46

标签: java spring instantiation

我是春天的新手,我有一个问题,我无法找到答案 - 在方法执行期间,我需要以预定义的数量创建托管bean的新实例(scope == prototype):

@Component
class SomeClass
{
     @Resource
     private ConnectionFactory conFactory;

     private Set <Client> clients;

     @Value ("${clientsNum}")
     private int clientsNum; 

     public void init ()
     {
         Client client = null;    //an interface, that the managed bean implements.

         for (int i = 0; i < clientsNum; i++)
         {
               client = ... //how to get a new client instance? 
               clients.add (client);
               client.doSomething ();
         }
     }

     public void shutdown ()
     {
         for (Client client : clients)
               client.shutdown ();

         conFactory.shutdown ();
     }
 }

我该怎么做?

我知道我可以使用init-method \ @PostConstruct注释(和匹配的destroy方法),但我不知道如何根据所需的数量获取实例。

我在过去几天搜索了这个问题,并阅读了有关服务定位器,查找方法和工厂bean的信息。他们都使用CGLIB(我更喜欢不使用)或spring的ApplicationContext(在spring的实现中创建依赖),最重要的是 - 他们不会在方法调用期间处理bean的创建(或者至少 - 我没有'了解如何在调用期间使用它们。

请协助。

感谢。

修改

最终我意识到我必须使用CGLIB或Spring的应用程序上下文,我选择使用service locator选项。

3 个答案:

答案 0 :(得分:0)

我猜某种类型的工厂对你来说是更好的选择,你可以定义一个工厂方法,它将clientsNum作为参数并返回给你。这样,您可以隐藏服务类中的所有详细信息。 如果您仍希望使用依赖注入执行此操作,则可以尝试方法注入。看看下面的代码就可以了解一下。

@Component
class SomeClass
{
 @Resource
 private ConnectionFactory conFactory;
 protected abstract Client createClient();

 private Set <Client> clients;

 @Value ("${clientsNum}")
 private int clientsNum; 

 public void init ()
 {
     Client client = null;    //an interface, that the managed bean implements.

     for (int i = 0; i < clientsNum; i++)
     {
           client = createClient();
           clients.add (client);
           client.doSomething ();
     }
 }

 public void shutdown ()
 {
     for (Client client : clients)
           client.shutdown ();

     conFactory.shutdown ();
 }
}

您可以通过简单的Google搜索找到方法注入的完整示例。但我建议采用第一种解决方案,它更干净。

答案 1 :(得分:0)

我担心您必须使用CGLIB或ApplicationContext,因为您需要托管bean

查找方法注入

SomeClass添加lookup method

@Lookup
private Client createClient() {
  return null; // Never mind, this method will be overridden
}

然后在init()中,您可以调用它:

client = createClient();

请注意,在Spring 4.1.0中引入了@Lookup注释。如果您使用的是旧版本,则需要XML配置。

使用ApplicationContext

声明自动有线属性:

@Autowired
private ApplicationContext applicationContext;

init()

client = applicationContext.getBean(Client.class);

答案 2 :(得分:0)

  

我不知道如何在不使用注入的情况下获取托管bean的新实例,但是在方法调用期间。

注入Spring ApplicationContextand,然后使用ApplicationContext.getBean(...)

 @Autowired
 private ApplicationContext applicationContext;

 public void init ()
 {
     Client client = null;    //an interface, that the managed bean implements.
     for (int i = 0; i < clientsNum; i++)
     {
/*>>>>*/   client = applicationContext.getBean(Client.class); 
           clients.add (client);
           client.doSomething ();
     }
 }