[英]CDI deferred injection is not working
在下一個場景中,我遇到了CDI的問題/問題:
Initializator注入ServletContextListener中。 但是在執行其他“步驟”之后,將調用方法啟動:
@WebListener
public class ContextListener implements ServletContextListener {
@Inject
private Initializator initializator;
public void contextInitialized(ServletContextEvent event) {
ServletContext servletContext = (ServletContext) event.getSource();
String contextPath = ((ServletContext) event.getSource()).getContextPath();
String serverName = servletContext.getInitParameter("SERVER_NAME");
initializator.startup(serverName);
System.out.println("ServletContext " + contextPath + " stated.");
}
public void contextDestroyed(ServletContextEvent event) {
String contextPath = ((ServletContext) event.getSource()).getContextPath();
System.out.println("ServletContext " + contextPath + " stopped.");
}
}
該存儲庫已成功注入初始化器中:
public class Initializator {
@Inject
private ChannelRepository repo;
public String serverName;
public void startup(String aServerName) {
this.serverName = aServerName;
initAll();
}
private void initAll() {
List<Channel> channels = repo.getChannels();
for (Channel channel : channels) {
channel.start();
}
}
}
存儲庫檢索數據並實例化通道:
public class ChannelRepository {
public List<Channel> getChannels() {
List<Channel> channels = new ArrayList<Channel>();
// ...some db access via jdbc (or jpa)
channels.add(new Channel("dummy", 8080));
return channels;
}
}
該通道需要一個記錄器:
public class Channel extends Thread {
@Inject
private Logger logger;
public String name;
public int port;
public Channel(String aName, int aPort) {
this.name = aName;
this.port = aPort;
}
@Override
public void run() {
logger.log("Channel " + name + " is running in port " + port);
// ...some other things to do
}
}
如何避免手動創建Channel實例?
之所以解決此問題,是因為實例構造之后調用了Initializator中的啟動方法。
如何管理這種“延遲”注射?
避免手動創建Channel實例
new Channel()
相當容易。
首先,我們需要在Channel類中使用默認構造函數,並在channel屬性中使用setter方法。
然后,您必須將此添加到您的頻道回購中
@Inject
Instances<Channel> channelInstances;
並在您的回購方法中從
channels.add(new Channel("dummy", 8080));
至
Channel channel = channelInstances.get();
channel.setPort(8080);
channel.setName("dummy");
channels.add(channel);
一個小提示:如果有可能,不要讓Channel擴展Thread,而是執行以下操作
final Channel channel = channelInstances.get();
channel.setPort(8080);
channel.setName("dummy");
channels.add(new Thread() {
@Override
public void run() {
channel.doTheChannelStuff();
channelInstances.destroy(channel);
}
}
為什么要這樣做:
在某些情況下,以嘗試使用的方式進行操作時會引入內存泄漏。 (有一個類似的問題在起作用)這與依賴范圍(默認)的依賴關系和新實例的“手動”創建有關。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.