自动布线在springboot应用程序中不起作用

自动布线在springboot应用程序中不起作用,spring,swing,spring-boot,jframe,Spring,Swing,Spring Boot,Jframe,我正在尝试使用JFrame创建一个Spring引导应用程序。我可以在applicationContext中看到我的bean,但它们没有自动连接。我找不到这个问题的原因。有人能帮我吗 代码如下: JavauiApplication-它显示userManager和userNameRepository都是bean InputNameForm.java->用户管理器为空 UserManager.java->用户名存储库为空 这是一个非常常见的问题,因为新手不了解IoC容器是如何工作的 首先,BeanDe

我正在尝试使用JFrame创建一个Spring引导应用程序。我可以在applicationContext中看到我的bean,但它们没有自动连接。我找不到这个问题的原因。有人能帮我吗

代码如下:

JavauiApplication-它显示userManager和userNameRepository都是bean

InputNameForm.java->用户管理器为空

UserManager.java->用户名存储库为空


这是一个非常常见的问题,因为新手不了解IoC容器是如何工作的

  • 首先,
    BeanDefinitionReader
    从XML、注释(
    @Component
    @Service
    等)、JavaConfig或Groovy脚本读取有关bean的元数据
  • 有几个
    BeanPostProcessor
    ,负责读取您正在编写的所有Spring注释(
    @Autowired
    等)
  • BeanFactory创建所有BeanPostProcessor,然后创建所有bean
  • 如果通过
    new
    操作符使用
    @Autowired
    依赖项创建bean,会发生什么?没什么,因为它实际上不是豆子。您创建的对象与IoC容器无关。如果使用@Component(例如)标记bean,则该bean可能已经存在于
    ApplicationContext
    中,但是通过
    new
    操作符创建的对象不会被Spring处理(注释将不起作用)

    希望这有帮助


    PS:生命周期简化了。

    几天前我也遇到了同样的问题。我了解的是,像netbeans附带的GUI构建器一样,GUI构建器将使用new关键字自动创建组件。这意味着这些组件将不会由spring管理。代码通常如下所示:

    private void initComponents() {
        jPanel1 = new javax.swing.JPanel(); //This component will not be managed by spring.
        //...
    }
    
    您可以使用下面提供的类来实现它

    @Component
    public class BeanProvider {
        private static ApplicationContext applicationContext;
    
        // Autowires the specified object in the spring context
        public static void autowire(Object object) {
            applicationContext.getAutowireCapableBeanFactory().autowireBean(object);
        }
    
        @Autowired
        private void setApplicationContext(ApplicationContext applicationContext) {
            BeanProvider.applicationContext = applicationContext;
        }
    }
    
    顶级SwingApp类:

    @SpringBootApplication
    public class SwingApp implements CommandLineRunner {
    
        public static void main(String[] args) {
            new SpringApplicationBuilder(SwingApp.class)
                    .headless(false).bannerMode(Banner.Mode.OFF).run(args);
        }
    
        @Override
        public void run(String... args) throws Exception {
            SwingUtilities.invokeLater(() -> {
                MainFrame frame = new MainFrame();
                frame.setVisible(true);
            });
        }
    }
    
    大型机类:

    public class MainFrame extends javax.swing.JFrame {
        public MainFrame() {
            initComponents();
        }
        private void initComponents() {
            //Gui Builder generated code. Bean not managed by spring. 
            //Thus, autowired inside CustomPanel won't work if you rely on ComponentScan. 
            jPanel1 = new CustomJPanel();         
            //...
        }
        private CustomJPanel jPanel1;
    }
    
    要在其中自动关联内容的panel类:

    //@Component //not needed since it wont work with gui generated code.
    public class CustomJPanel extends javax.swing.JPanel{
        @Autowired
        private SomeRepository someRepository
        public CustomJPanel(){
            BeanProvider.autowire(this); //use someRepository somewhere after this line.
        }
    }
    

    我在JavaFx项目中也遇到同样的问题。服务和组件注释类在UI控制器中为null,即使它在创建时的上下文中显示。下面的代码对我有用

    @Component
    public class FxmlLoaderWithContext {
    private final ApplicationContext context;
    
    @Autowired
    public FxmlLoaderWithContext(ApplicationContext context) {
        this.context = context;
        FXMLLoader fxmlloader = new FXMLLoader();
        fxmlloader.setControllerFactory(context::getBean); //this row ensure services and components to be autowired
    }
    

    }

    使用新关键字自己创建一个
    InputNameForm
    实例。Spring不知道这个实例,因此没有注入任何东西。可能是@dunni I autowired InputNameForm的重复,现在它也变成了null。它得到了修复。我将实例设置为静态,以调用内部void main。当我用appContext.getBean(InputNameForm.class)替换它时,一切都正常了
    public class MainFrame extends javax.swing.JFrame {
        public MainFrame() {
            initComponents();
        }
        private void initComponents() {
            //Gui Builder generated code. Bean not managed by spring. 
            //Thus, autowired inside CustomPanel won't work if you rely on ComponentScan. 
            jPanel1 = new CustomJPanel();         
            //...
        }
        private CustomJPanel jPanel1;
    }
    
    //@Component //not needed since it wont work with gui generated code.
    public class CustomJPanel extends javax.swing.JPanel{
        @Autowired
        private SomeRepository someRepository
        public CustomJPanel(){
            BeanProvider.autowire(this); //use someRepository somewhere after this line.
        }
    }
    
    @Component
    public class FxmlLoaderWithContext {
    private final ApplicationContext context;
    
    @Autowired
    public FxmlLoaderWithContext(ApplicationContext context) {
        this.context = context;
        FXMLLoader fxmlloader = new FXMLLoader();
        fxmlloader.setControllerFactory(context::getBean); //this row ensure services and components to be autowired
    }