【问题标题】:getting null values from bean从bean获取空值
【发布时间】:2016-08-01 07:15:24
【问题描述】:

嗨,我想了解 bean 中的自动装配,我能够自动装配,但这里仍然得到空值是代码 sn-ps

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

 @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 值, 那么为什么我将这个值设为 null,我该如何排序呢?

编辑

输出是

log4j:WARN 找不到记录器的附加程序 (org.springframework.core.env.StandardEnvironment)。 log4j:请警告 正确初始化 log4j 系统。 log4j:WARN 见 http://logging.apache.org/log4j/1.2/faq.html#noconfig 了解更多信息。 空空

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

【问题讨论】:

  • 你的类的包名是什么?
  • 那是包名还是文件夹结构?
  • 我的课程在java 包中,文件夹str 是test.java.AA 是课程)
  • @Jens 我错过了什么吗?
  • @ComponentScan(basePackages = { "*.java" }) 必须在 @Configuration 注释文件中,而不是在 @Service 注释文件中。

标签: java spring


【解决方案1】:

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

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

在您的代码中,您已将 AB 标记为 @Components,这意味着它们将使用默认构造函数,使用默认值将它们实例化为 bean .

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

如果告诉 Spring 你的 bean,你需要选择 one 方式,所以你可以从 AB 中删除 @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
}

【讨论】:

  • 用您更新后问题的解决方案更新了答案
  • 实际上我正在混合两种方法,即@component@confuguration 现在正在引起歧义,我知道在任何一种情况下该怎么做,顺便说一句谢谢:)
【解决方案2】:

您收到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
     }
    }
    

如果你用@Component注解了类A,那么你应该不能注册它两次,所以你应该选择一种方式——要么使用@Component注解,要么在Config中手动定义它@Bean 注解的方法中的类。

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

package java;

?

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

【讨论】:

  • package test.java 我仍然得到相同的输出
  • 现在我明白了,你是对的,我打电话给A & B 两次,一次是@component,另一次是@configuration
  • @themountain,package test;,而不是package test.java.java 是一个 file 扩展名,您应该将其用于编写类定义的文件(这些是被编译的文件)。我建议您浏览官方 Java 教程中的 Packages 章节:docs.oracle.com/javase/tutorial/java/package/packages.html。它简洁明了,肯定能把事情弄清楚。 :)
  • 感谢您的提示,但我已经使用 package com.java.test.somepackage 之类的工具了,它从未造成任何麻烦,但我会处理的(你增加了我的工作量,哈哈;))顺便说一句,谢谢您的提示 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-17
  • 2015-07-04
  • 1970-01-01
  • 1970-01-01
  • 2015-04-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多