Java lazy init=";真的;。它能做什么?为什么我不能在没有lazyint设置为true的情况下从Swing应用程序中获取Springbean?

Java lazy init=";真的;。它能做什么?为什么我不能在没有lazyint设置为true的情况下从Swing应用程序中获取Springbean?,java,multithreading,spring,swing,jakarta-ee,Java,Multithreading,Spring,Swing,Jakarta Ee,我有一个在后端部署轻量级HTTP服务器(Jetty)的应用程序。 servlet基本上更新了MySQL数据库。 我用弹簧把所有的东西都接线好了 到目前为止还可以 我有一个与服务器交互的UI。 如果UI在本地运行,我希望它在JTree中显示当前登录的用户 因此,我决定启动服务器,即在启动主框架时启动Spring 最重要的是,为了更新UI的JTree以显示所有登录的用户,我想使用Observer Observable,并让接受连接的代码成为一个Observable ConnectionListene

我有一个在后端部署轻量级HTTP服务器(Jetty)的应用程序。
servlet基本上更新了MySQL数据库。
我用弹簧把所有的东西都接线好了

到目前为止还可以

我有一个与服务器交互的UI。
如果UI在本地运行,我希望它在
JTree
中显示当前登录的用户

因此,我决定启动服务器,即在启动主框架时启动Spring

最重要的是,为了更新UI的JTree以显示所有登录的用户,我想使用Observer Observable,并让接受连接的代码成为一个
Observable

ConnectionListener
将收到将传入连接存储在
ArrayBlockingQueue
中的通知,而
Jtree
的后台线程(具有对
DefaultMutableTreeNode
根的引用)将通过
SwingUtilities
在EDT线程中更新它

我的问题如下:

如果我这样做:

  public class AdminFrame extends JFrame {
      public static ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("myBeans");    

public static void main(String[] args){    
      EventQueue.invokeLater(new Runnable() {
                public void run() {
        //Show GUI
         }
        }
    }
GUI没有绘制,但我可以理解,因为一旦Spring启动,服务器启动,线程就不会返回

因此,我在后端线程中启动Spring,如下所示:

public class ServerThread extends Thread {  
    @Override
    public void run() {  
    ClassPathXmlApplicationContext ctx = ApplicationCtx.getApplicationCtx();  
    }  
}
public class AdminFrame extends JFrame {  
    public static void main(String[] args) {  
       ServerThread lightweightServer = new ServerThread();  
       lightweightServer.start();
       Thread.sleep(9000);//Temporary solution to make sure the server is started up before GUI
        ConnectHandler connectHandler = (ConnectHandler) ApplicationContext.getApplicationCtx().getBean("connectHandler");
        connectHandler.addObserver(new ConnectionListener());  
        EventQueue.invokeLater(new Runnable() {  
        public void run() {  
              //SHOW GUI
              }  
         }

}

GUI现在显示出来,看起来还可以,但我错过了通知

问题:

无法获取新连接的通知:

1) 如果我按以下方式注册通知:

public class ServerThread extends Thread {  
    @Override
    public void run() {  
    ClassPathXmlApplicationContext ctx = ApplicationCtx.getApplicationCtx();  
    }  
}
public class AdminFrame extends JFrame {  
    public static void main(String[] args) {  
       ServerThread lightweightServer = new ServerThread();  
       lightweightServer.start();
       Thread.sleep(9000);//Temporary solution to make sure the server is started up before GUI
        ConnectHandler connectHandler = (ConnectHandler) ApplicationContext.getApplicationCtx().getBean("connectHandler");
        connectHandler.addObserver(new ConnectionListener());  
        EventQueue.invokeLater(new Runnable() {  
        public void run() {  
              //SHOW GUI
              }  
         }
GUI从未出现。如果我删除该行:

 ConnectHandler connectHandler = (ConnectHandler) ApplicationContext.getApplicationCtx().getBean("connectHandler");  
GUI显示出来

2) 如果我在EDT内注册,即在
AdminFrame
的构造函数内注册,GUI也不会显示。

再次,如果我删除以下行,GUI将显示,但这样我无法注册以获取通知:

 ConnectHandler connectHandler = (ConnectHandler) ApplicationContext.getApplicationCtx().getBean("connectHandler");  
这一定是线程问题,但我不明白问题出在哪里。
为什么第二次调用Spring应用程序上下文以获取
ConnectHandler
使线程不返回?
我做错了什么


更新:

如果我在Spring配置文件中向启动Jetty服务器的bean添加属性
lazy init=“true”
,问题就解决了。
但我不明白为什么它能解决这个问题,或者问题是什么

谢谢

  • Serializable
    Observate
    需要将GUI相关代码包装成(在大多数情况下)
    invokeAndWait()

  • 来自
    SwingWorker
    (因为是有保证的,但我看到一些情况并不像我期望的那样工作)或
    Runnable\Thread
    需要将GUI相关代码强制转换为
    invokeLater()

  • 您可以在之前准备好GUI(然后存在EDT)和可见性

对于这个
容器
您必须在内部调用
invokeXxx()或最好是来自
javax.swing.Action()

  • Serializable
    Observate
    需要将GUI相关代码包装成(在大多数情况下)
    invokeAndWait()

  • 来自
    SwingWorker
    (因为是有保证的,但我看到一些情况并不像我期望的那样工作)或
    Runnable\Thread
    需要将GUI相关代码强制转换为
    invokeLater()

  • 您可以在之前准备好GUI(然后存在EDT)和可见性


对于这个
容器
您必须在内部调用
invokeXxx()或者最好是来自
javax.swing.Action()

如果设置lazy init来解决您的问题,我认为它还没有完全解决

默认情况下,所有bean都在启动时初始化,因此如果任何bean没有正确初始化,那么启动时就会出现问题


若您将其设置为false,那个么bean将不会被调用,您也不会面临任何ISSUE。因此,问题没有得到解决,而是被推迟了。

如果设置lazy init来真正解决您的问题,我认为它还没有完全解决

默认情况下,所有bean都在启动时初始化,因此如果任何bean没有正确初始化,那么启动时就会出现问题


若您将其设置为false,那个么bean将不会被调用,您也不会面临任何ISSUE。因此,问题没有得到解决,而是被推迟了。

我或多或少知道这些问题。我只是不明白为什么调用
ConnectHandler ConnectHandler=(ConnectHandler)ApplicationContext.getapplicationtx().getBean
会阻止GUI显示,我在EDT内部或外部执行。我只想获得一个bean。Spring上下文是否在EDT外部初始化有关系吗?Spring不执行任何与GUI相关的操作。它主要连接EDT中的Jetty服务器backend@user384706一定有一些代码,未编码流,连接,未刷新,流,文件,未关闭且在I/O级别仍处于活动状态的连接,或者错误地调用未初始化类,返回null,那么GUI为null,解决方案SwingExplorer,如果返回未初始化的内容,那么JProfiler,很幸运,
lazy init
观察结果如何。一旦我将
lazy init
设置为false,代码就可以正常工作。请参阅Posthaaaaa:-)上的更新,也许只有这样才能返回值:-),难道没有更稳定的。。。。。。。顺便说一句,我的+1对于优秀的问题如果
lazy init=“true”
有帮助,你会想知道GUI组件(或其模型)是否是在EDT之外构建的
EventQueue.isDispatchThread()
可能会提供信息。我或多或少知道这些问题。我只是不明白为什么调用
ConnectHandler ConnectHandler=(ConnectHandler)ApplicationContext.GetApplicationTX().getBean
会阻止GUI显示,无论我是在EDT内部还是在EDT外部执行。我只是想得到一个答案
JFrame#pack(); 
JFrame#setVisible(true);