为了账号安全,请及时绑定邮箱和手机立即绑定

具有AnnotationConfigApplicationContext的Spring应用程序:

具有AnnotationConfigApplicationContext的Spring应用程序:

森栏 2022-12-28 11:03:15
这是我的一个 SO 问题的延续。我扩展了同一个例子,我希望它能工作,但是我得到了 NullPointerException。这是完整的源代码:FirstBean.javapackage com.example;import org.springframework.stereotype.Component;@Componentpublic class FirstBean {    public FirstBean() {    }    private String name;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @Override    public String toString() {        return "FirstBean [name=" + name + "]";    }}SomeBean.javapackage com.example;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.stereotype.Component;@Component@Configuration@ComponentScan(basePackages = { "com.example" })public class SomeBean {    @Autowired    private FirstBean fb;    @Bean    FirstBean instantiateFirstBean() {        return new FirstBean();    }    public SomeBean() {        // this.fb.setName("Some Name"); -> this was causing problem as         // bean isn't still created fully    }    public void print() {        this.fb.toString();     }        @PostConstruct    void post() {        fb.setName("Some name");    }}
查看完整描述

1 回答

?
森林海

TA贡献2011条经验 获得超2个赞

我认为这是因为 Spring 将首先必须实例化您的SomeBean类,然后它将尝试FirstBean通过反射自动装配,因为您@Autowired在字段上放置了注释。


您正在尝试访问构造函数中的FirstBean依赖项,但是当调用SomeBean构造函数时,在创建上下文时,依赖项为空,因为 Spring 尚未自动装配依赖项 - 它会在对象创建后尝试通过反射自动装配它。这就是你到达那里的原因。你的班级也会发生同样的情况——决定一种方法。SomeBeanFirstBeanNullPointerExceptionSomeBean


此外,奇怪的是,您创建的类都用@Configuration和进行了注释@Component。请参阅此 SO 问题以查看潜在错误。


此外,您的配置中存在一些问题。您使用注释FirstBean进行@Component注释,并且您仍然创建了一个@Bean返回此类实例的带注释的方法。您应该决定一种方法 - 您使用注释为应用程序上下文实例化它,@Bean或者使用注释此类,@Component然后让组件扫描自动为您创建它。


编辑:


您应该决定是要使用@ComponentScan还是要通过@Bean注释为上下文创建 bean - 现在您正在混合不同的类型,并且在尝试按类型自动装配时会因重复的 bean 定义而出错,因为在您当前的实现中会有在您的上下文中是 2 个 beanSomeBean和 2 个 bean FirstBean- 它们只会有不同的 ID。请注意,我用 NPE 期望指出的错误与它无关。我将提出一个使用自动包扫描的解决方案:


FirstBean类


@Component

public class FirstBean {


    private String name;


    public String getName() {

        return name;

    }


    public void setName(String name) {

        this.name = name;

    }


    @Override

    public String toString() {

        return "FirstBean [name=" + name + "]";

    }

}

SomeBean类


@Component

public class SomeBean {


    private FirstBean fb;


    @Autowired

    public SomeBean(FirstBean firstBean) {

        this.fb = firstBean;

        this.fb.setName("Some Name");

    }


    public void print() {

        this.fb.toString();

    }

}

我的配置类


@Configuration

@ComponentScan(basePackages = { "com.example" })

public class MyConfig {


}

主驱动类


@Component

public class MainDriver {


    @Autowired

    private Environment env;


    @Autowired

    protected ConfigurableEnvironment cenv;


    @Autowired

    ApplicationContext ctx;


    @Autowired

    private SomeBean sb;



    public static void main(String[] args) {


        ApplicationContext ctx = new AnnotationConfigApplicationContext(MyConfig.class);


        MainDriver l = ctx.getBean(MainDriver.class);

        System.out.println("In main() the ctx is " + ctx);

        l.test();

    }


    public void test() {

        System.out.println("hello");

        sb.print();

    }

}


查看完整回答
反对 回复 2022-12-28
  • 1 回答
  • 0 关注
  • 94 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号