Java 从bean获取空值

Java 从bean获取空值,java,spring,Java,Spring,嗨,我正在尝试理解bean中的自动连接,我能够自动连接,但这里仍然得到空值是代码片段 使用当前输出编辑了整个代码 @Component public class A { private String value; private B b; public void display() { System.out.println(value); System.out.println(b.m()); } public Stri

嗨,我正在尝试理解bean中的自动连接,我能够自动连接,但这里仍然得到空值是代码片段

使用当前输出编辑了整个代码

 @Component
public class A {
    private String value;
    private B b;

    public void display() {
        System.out.println(value);
        System.out.println(b.m());
    }

    public String getValue() {
        return value;
    }


    public void setValue(String value) {
        this.value = value;
    }

    public B getB() {
        return b;
    }

    @Autowired
    public void setB(B b) {
        this.b = b;
    }

}
B级

@Component
public class B {

    private String b;

    public void setB(String b) {
        this.b = b;
    }

    public String m() {
        return b;
    }

}
configuration.java

@Service
@ComponentScan(basePackageClasses = A.class)
public class AppConfig {

    @Autowired
    public A setBean() {
        A a = new A();
        a.setValue("inside A");
        return a;
    }

    @Autowired
    public B setB() {
        B b = new B();
        b.setB("inside B");
        return b;
    }
}
Main

 @ContextConfiguration(classes = AppConfig.class)
public class Application {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext(
                AppConfig.class);
        A app = (A) configApplicationContext.getBean("a");
        app.display();
    }

}
现在的问题是,我应该得到所有的值,但不是从每个bean得到空值, 那么,为什么我将这个值设为null,以及如何对其进行排序呢

编辑

输出是

log4j:警告:找不到记录器的附加器 (org.springframework.core.env.StandardEnvironment)。log4j:请警告 正确初始化log4j系统。log4j:请参阅 更多信息。 空值


Edit调试后,我发现,在config类中,它正在按指定传递值,但在
display()
中显示值时,它会给出null

可能导致您接收
null
值的原因:

  • @组件
    应使用大写字母书写,并且必须导入Spring包中的正确注释

  • 类“ApCfg”应如下所示:

    @Configuration // this annotation is needed by Spring to know it is a config class
    @ComponentScan(basePackages = { "java" }) // you have to add the package NAMES here, not a regex
    public class ApCfg {
    
    @Bean // here, you're telling Spring to register a bean in its container, so you have to mark it as so, by using the @Bean annotation
    public A getA() {
        A a = new A(); // constructors are methods too, so they need to be called, using paranthesis
        a.setAValue("asdf"); // setters usually return void, so you shouldn't be able to return this
        return a; // this instance here is what will be registered in the container
     }
    }
    
  • 如果您已经用
    @Component
    注释了类
    A
    ,那么您应该不能注册它两次,所以您应该选择一种方法-或者使用@Component注释,或者在配置类中用@Bean注释的方法手动定义它

    此外,我倾向于同意您选择的包名是相当特殊的。您确定类顶部的包定义是:

    package java;
    
    ?


    如果你没有任何以
    包开始的语句,那么你所有的类都在
    默认的
    包中,在这种情况下,我强烈建议将它们分组到真正的包中。

    看来你还没有完全理解
    @Autowired
    @Bean
    之间的区别,和
    @组件

    • @Autowired
      意味着应将字段或方法设置为Autowired(注入)bean,或使用Autowired(注入)bean调用该字段或方法
    • @Bean
      用于标记有
      @Configuration
      的类中,以告知Spring可以自动连接的Bean
    • @Component
      用于一个类,告诉Spring这个类应该被实例化为一个可以自动连接的bean
    在代码中,您已经将A和B标记为
    @Component
    s,这意味着它们将使用默认构造函数和默认值实例化为bean

    然后,您尝试(再次)在AppConfig中将它们实例化为bean,但使用了
    @Autowired
    来标记这些定义,这意味着Spring不会获取它们

    如果要告诉Spring您的Bean,您需要选择一种方式,这样您可以从A和B中删除
    @Component
    ,并在AppConfig中创建它们的方法上使用
    @Bean
    ,而不是
    @Autowired
    ,或者从AppConfig中完全删除bean定义,并在构建时初始化A和B中的成员

    第一种选择:

    // No @Component here
    public class A {
        ...
    }
    
    // No @Component here
    public class B {
        ...
    }
    
    @Configuration
    // You probably don't need @ComponentScan anymore since
    // no classes are annotated with @Component
    @ComponentScan(basePackageClasses = A.class)
    public class AppConfig {
    
        @Bean
        public A setBean() {
            A a = new A();
            a.setValue("inside A");
            return a;
        }
    
        @Bean
        public B setB() {
            B b = new B();
            b.setB("inside B");
            return b;
        }
    }
    
    第二种选择:

    @Component
    public class A {
        private String value = "inside A";
        ...
    }
    
    @Component
    public class B {
        private String b = "inside B";
        ...
    }
    
    @Configuration
    @ComponentScan(basePackageClasses = A.class)
    public class AppConfig {
        // No bean definitions here, but required for @ComponentScan
    }
    

    你的类的包名是什么?那是包名还是文件夹结构?我的类在
    java
    package中,文件夹str是
    test.java.A
    A
    is class)@Jens我遗漏了什么吗?
    @ComponentScan(basePackages={“*.java”})
    必须在
    @配置
    注释文件中,而不是在
    @服务
    注释文件中。
    包测试。java
    和我仍然得到相同的输出现在我明白了重点,你是对的,我两次调用
    a&B
    ,一次是由
    @组件
    调用,另一次是由
    @配置
    @山调用,
    封装测试
    ,而不是
    包测试.java
    .java
    是一个文件扩展名,应该用于编写类定义的文件(这些是编译的文件)。我建议您浏览官方Java教程中的包一章:。它简洁明了,肯定能把事情弄清楚。:)谢谢你的提示,但是我已经使用了像
    package com.java.test.somepackage
    ,它从来没有引起任何麻烦,但我会处理好的(你增加了我的工作量lol;))顺便说一句谢谢你的提示:)用你更新的问题的解决方案更新了答案实际上我混合了两种方法,也就是说,
    @component
    @confuguration
    现在造成了麻烦,我知道在这两种情况下该怎么办了,顺便说一句,谢谢:)