从bean获取空值

时间:2016-08-01 07:15:24

标签: 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 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;
    }
}

主要

 @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:WARN找不到记录器的appender   (org.springframework.core.env.StandardEnvironment)。 log4j:警告请   正确初始化log4j系统。 log4j:警告请参阅   http://logging.apache.org/log4j/1.2/faq.html#noconfig了解更多信息。   null null

编辑调试后,我发现,在配置类中,它传递了指定的值,但是当它在display()中显示值时,它给出了空

2 个答案:

答案 0 :(得分:0)

您收到null值的可能原因:

  1. @Component应该用大写字母书写,并且必须导入Spring包中的正确注释;

  2. 类'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
     }
    }
    
  3. 如果您使用A注释了类@Component,那么您应该无法注册两次,因此您应该选择一种方法 - 使用@Component注释,或者定义它在由@Bean注释的方法中在Config类中手动。

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

    package java;
    

    如果您没有以package开头的任何语句,那么您所有的课程都在default包中,在这种情况下,我强烈建议您将它们分组到真正的包中代替。

答案 1 :(得分:0)

您似乎还没有完全理解@Autowired@Bean@Component之间的区别。

  • @Autowired表示应使用自动连接(注入)bean设置或调用字段或方法。
  • @Bean用于标有@Configuration的类,告诉Spring有关可以自动装配的bean
  • @Component用于告诉Spring该类应该被实例化为可以自动装配的bean。

在您的代码中,您已将 A B 标记为@Component,这意味着它们将使用其默认构造函数实例化为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
}