【问题标题】:Spring get managed beans during a method invocationSpring在方法调用期间获取托管bean
【发布时间】:2014-09-28 12:52:46
【问题描述】:

我是 spring 新手,我有一个问题我找不到答案 - 在方法执行期间,我需要以预定义的数量创建托管 bean(范围 == 原型)的新实例:

@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 选项。

【问题讨论】:

  • 您要解决的问题是什么? - 我认为您找不到合理答案的原因是,您想以一种不灵活的方式解决问题。 - 所以我问这个问题。
  • 我不知道如何在不使用注入但在方法调用期间获取托管 bean 的新实例。

标签: java spring instantiation


【解决方案1】:

恐怕你必须使用 CGLIB 或 ApplicationContext,因为你想要一个托管 bean

查找方法注入

lookup method 添加到您的SomeClass

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

然后在init(),你可以直接调用它:

client = createClient();

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

使用 ApplicationContext

声明一个自动连接的属性:

@Autowired
private ApplicationContext applicationContext;

init():

client = applicationContext.getBean(Client.class);

【讨论】:

  • 谢谢。我意识到我必须使用 CGLIB 或 Spring 的应用程序上下文。最终,我决定使用服务定位器。
【解决方案2】:

我想某种类型的工厂对你来说会是一个更好的选择,你可以定义一个工厂方法,它以 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 搜索找到方法注入的完整示例。但我建议使用第一个解决方案,它更干净。

【讨论】:

    【解决方案3】:

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

    注入Spring ApplicationContext然后使用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 ();
         }
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-12
      • 2013-01-24
      • 1970-01-01
      • 1970-01-01
      • 2012-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多