我是春天的新手,我有一个问题,我无法找到答案 - 在方法执行期间,我需要以预定义的数量创建托管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选项。
答案 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配置。
声明自动有线属性:
@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 ();
}
}