我们希望通过注解(不提供 @Autowired)或 XML(不提供 default-autowire 或 bean 中的 autowire 属性) 的方式,在 IndexService 中,通过构造函数注入 UserService,那么 UserService 是否可以注入成功呢?
使用注解
@Component
public class UserService {
}
@Component
public class IndexService {
public IndexService(UserService userService){
System.out.println(userService);
}
}
@Configuration
@ComponentScan("org.wesoft.spring.constructor")
public class AppConfig {
}
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
ac.register(AppConfig.class);
ac.refresh();
}
}
运行结果如下:成功打印了 UserService,表示注入成功
org.wesoft.spring.constructor.bean.UserService@dd3b207
使用 XML
XML 中没有指定任何自动装配模式,只是简单的指定了 2 个 bean
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
>
<bean id="indexService" class="org.wesoft.spring.constructor.bean.IndexService">
</bean>
<bean id="userService" class="org.wesoft.spring.constructor.bean.UserService">
</bean>
</beans>
public class UserService {
}
public class IndexService {
public IndexService(UserService userService){
System.out.println(userService);
}
}
@Configuration
@ComponentScan("org.wesoft.spring.constructor")
@ImportResource("classpath:applicationContext.xml")
public class AppConfig {
}
运行结果如下:成功打印了 UserService,表示注入成功
org.wesoft.spring.constructor.bean.UserService@dd3b207
分析
你一定感到很奇怪,我们并没有使用 @Autowired 注解,也没有再 XML 中配置 default-autowire,那么 Spring 到底是如何做到的呢?
这就要从源码进行分析了,Spring 源码中有这么一段
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
从源码来看,Spring 首先推断构造函数,然后判断构造函数是否不等于空,然后,再判断自动注入模型,是否等于 AUTOWIRE_CONSTRUCTOR,很明显,我们并没有指定 AutowireMode,所以这里是不成立的
如果我们有且只提供一个合理的构造函数,这里的合理是指,Spring 可以从容器中找到对应的 bean 作为入参,那么就可以完成注入,这里和注入模型并没有什么关系,只是 Spring 提供的一种构造方法注入技术而已,叫做推断构造函数
后期我会详细介绍,这里只是说明一下,构造函数为什么可以完成注入