先看一个简单的例子
public class Parent {
class Child{
}
public static void main(String[] args) {
AnnotationConfigApplicationContext
context = new AnnotationConfigApplicationContext();
context.register(Child.class);
context.refresh();
System.out.println(context.getBean(Child.class));
}
}
上面的例子可以看到,实例化内部类失败
一个java对象 要想成为一个bean,必须要经过锻造,这个过程称之为bean的生命周期
其中有一个非常重要的步骤:推断构造方法
spring在实例化Child的时候,必定要先去get Parent,但是get不到,因为我们并没有实例化Parent,所以报错No qualifying bean of type 'com.spring.Parent'。
Child作为Parent的内部类,如果直接单纯的把Child注册给spring容器去实例化Child会失败;可以理解为Child是Parent的一个成员变量;
Parent没有注册给spring容器,站在spring角度而言就是没有Parent的对象,那么成员变量自然无法实例化;
原理是因为在实例化Child的时候,spring推断Child使用的构造方法会推断出来一个需要带Parent的构造方法
public Child(Parent parent){};
而且spring会使用这个构造方法去实例化Child,实例化Child的过程当中会去 getBean(Parent.class),故而失败;
解决方法:
1、把Child定义成为一个静态的内部类;这样就不需要Parent的对象就能实例化Child
2、给Child提供一个带Parent的构造方法,并且把Parent注册给spring容器
AbstractAutowireCapableBeanFactory
// 来推断一下这个类有哪些构造方法
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);