您好我正在尝试了解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()
中显示值时,它给出了空
答案 0 :(得分:0)
您收到null
值的可能原因:
@Component
应该用大写字母书写,并且必须导入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
}
}
如果您使用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
}