簡體   English   中英

CDI延遲注射不起作用

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM