简体   繁体   English

自动装配的 bean 在设置器之外是 null

[英]Autowired bean is null outside of setter

I injected a bean by setter into another bean in Spring Boot.我在 Spring Boot 中通过 setter 将一个 bean 注入到另一个 bean 中。 The bean is not null when inside the setter, but when I call it from another method, it returns null.在 setter 中,bean 不是 null,但是当我从另一个方法调用它时,它返回 null。

I've tried all combinations (injecting by constructor and setter, autowiring field only, autowiring field and setter...).我已经尝试了所有组合(通过构造函数和设置器注入,仅自动装配字段,自动装配字段和设置器......)。

SpringConfiguration.java SpringConfiguration.java

@Bean
public BeanToInject beanToInject(){
    return new BeanToInject();
}
@Bean
public TargetClass targetClass(){
    return new TargetClass();
}

BeanToInject.java BeanToInject.java

@Component
public class BeanToInject{
    public BeanToInject(){}
    //More stuff
}

TargetClass.java TargetClass.java

@Component
public class TargetClass {

    private BeanToInject beanToInject;

    public TargetClass(){}

    @Autowired
    public void setBeanToInject(BeanToInject beanToInject){
        this.beanToInject = beanToInject;
        System.out.print("1. " + this.beanToInject); //Here is instanced
    }

    public void anotherMethod(){
        System.out.print("2. " + beanToInject); //Here is null
        beanToInject.doSomeStuff(); //Here comes the exception
    }

}

Output: Output:

//Spring stuff...
1. com.foo.bar.BeanToInject@blahblah
2. null

//------And then, the exception

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
    at acteso.standard.deskapp.gui.LoginController.btAceptar(LoginController.java:82)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Node.fireEvent(Node.java:8411)
    at javafx.scene.control.Button.fire(Button.java:185)
    at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
    at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
    at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
    at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:432)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:410)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431)
    at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
    at com.sun.glass.ui.View.notifyMouse(View.java:937)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$3(WinApplication.java:177)
    at java.lang.Thread.run(Unknown Source)

I guess the exception won't be usefull at all.我想这个例外根本没有用。 I'm using JavaFX but it doesn't matter when the exception comes from Spring.我正在使用 JavaFX 但是当异常来自 Spring 时并不重要。

I don't know if I'm missing any annotation or if I have configured it wrong.我不知道我是否遗漏了任何注释,或者我是否配置错误。

Edit:编辑:

Actually it was a problem about Spring and JavaFX creating their own instances of TargetClass, so BeanToInject was duplicate.实际上这是关于 Spring 和 JavaFX 创建自己的 TargetClass 实例的问题,因此 BeanToInject 是重复的。 I solved it by making Spring manage the JavaFX controllers, following this tutorial: Add Spring to JavaFX .我通过让 Spring 管理 JavaFX 控制器解决了这个问题,遵循本教程: 将 Spring 添加到 Z47A34A9D6CE8F6ECB60788880707 Thanks to all for the help!感谢大家的帮助!

An example一个例子

BeanOne (BeanToInject) BeanOne (BeanToInject)

public class BeanOne {

}

BeanTwo ( TargetClass ) BeanTwo(目标类)

public class BeanTwo {

    BeanOne beanOne;


    @Autowired
    public void setBeanOne(BeanOne beanOne) {
        this.beanOne = beanOne;
        System.out.println("From setter "+beanOne);
    }

    public void testMethod() {
        System.out.println("From testMethod "+beanOne);
    }


}

Configuration.配置。 Note that, only @Bean is used here注意,这里只使用了@Bean

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class TestConfiguration {

    @Bean
    public BeanOne getBeanOne() {
        return new BeanOne();
    }

    @Bean
    public BeanTwo getBeanTwo() {
        return new BeanTwo();
    }
}

Test App测试应用

public class TestApp {

    public static void main(String[] args) {

        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(TestConfiguration.class);

        ctx.registerShutdownHook();

        BeanTwo bean = ctx.getBean(BeanTwo.class);

        bean.testMethod();
    }

}

The output when run output 运行时

From setter BeanOne@7f1302d6
From testMethod BeanOne@7f1302d6

Spring container injects the instance of BeanOne when BeanTwo is created. Spring 容器在创建 BeanTwo 时注入 BeanOne 的实例。 During this the "From setter" message gets printed.在此期间,“From setter”消息被打印出来。

Then we are obtaining this BeanTwo instance from the ApplicationContext and testMethod() is called, which gives the "From testMethod" message.然后我们从 ApplicationContext 中获取这个 BeanTwo 实例并调用 testMethod(),它给出了“From testMethod”消息。

From the way it looks, in your case you are creating the BeanTwo ( TargetClass ) instance on your own (new TargetClass() ).从它的外观来看,在您的情况下,您正在自己创建 BeanTwo ( TargetClass ) 实例 (new TargetClass() )。 Such a bean is not managed by the Spring Container and will have BeanOne reference as null when created.此类 bean 不受 Spring 容器管理,并且在创建时将具有 BeanOne 引用为 null。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM