🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
目录结构 ![](https://img.kancloud.cn/31/14/3114f12af2a27bac7e6699d27aa75d4d_425x378.png) 没有使用 spring 的构造器注入形式: ![](https://img.kancloud.cn/22/bb/22bbcf945082e53cf1ae8836ec338117_326x202.png) `DeclareSpringComponent`是用于 spring 的,暂时不理。 `ConstructorInjection`是普通构造器注入,`Dependency`是依赖项。通过在构造器中提供依赖项,实现基于构造器的依赖注入。 ~~~ // 注意 @Autowired 只能用于其中一个构造器自动注入 ~~~ --- 接着有个三个spring应用类: ![](https://img.kancloud.cn/a5/d3/a5d3ee3a0dcf921ade2d1e77b6cbce06_425x378.png) 其中 `DeclareSpringComponents` 就是演示使用 spring 构造器注入而已。 ~~~ public class DeclareSpringComponents { public static void main(String... args) { GenericXmlApplicationContext ctx = new GenericXmlApplicationContext(); ctx.load("classpath:spring/app-context-annotation.xml"); ctx.refresh(); MessageProvider messageProvider = ctx.getBean("provider", MessageProvider.class); System.out.println(messageProvider.getMessage()); ctx.close(); } } ~~~ 对应的 xml 配置文件: ~~~ <!--省略 schema --> <context:component-scan base-package="com.apress.prospring5.ch3.annotated"/> <bean id="message" class="java.lang.String" c:_0="希望你会好好的 I hope that someone gets my message in a bottle"/> <bean id="message2" class="java.lang.String" c:_0="I know I won't be injected :("/> ~~~ 上面配置文件扫描到 `com.apress.prospring5.ch3.annotated` 这个包下的 bean : ~~~ @Repository("provider") public class ConfigurableMessageProvider implements MessageProvider { private String message; // 根据参数名来自动注入,构造器注入 @Autowired public ConfigurableMessageProvider(String message) { this.message = message; } @Override public String getMessage() { return this.message; } } ~~~ 它对应的 `MessageProvider` 是: ~~~ @Repository("provider") public class ConfigurableMessageProvider implements MessageProvider { private String message; // 根据参数名来自动注入,构造器注入 @Autowired public ConfigurableMessageProvider(String message) { this.message = message; } @Override public String getMessage() { return this.message; } } ~~~ --- 接下来看看 `ConstructorConfusion` 这个类里边演示了两个构造器,spring 根据构造器的参数类型判断应该注入那个 bean. ~~~ public class ConstructorConfusion { private String someValue; //两个构造器注入,根据构造器参数的类型来判断注入哪一个 public ConstructorConfusion(String someValue) { System.out.println("ConstructorConfusion(String) called"); this.someValue = someValue; } public ConstructorConfusion(int someValue) { System.out.println("ConstructorConfusion(int) called"); this.someValue = "Number: " + someValue; } public static void main(String... args) { GenericXmlApplicationContext ctx = new GenericXmlApplicationContext(); ctx.load("classpath:spring/app-context-xml.xml"); ctx.refresh(); ConstructorConfusion cc = (ConstructorConfusion) ctx.getBean("constructorConfusion"); System.out.println(cc); ctx.close(); } public String toString() { return someValue; } } ~~~ 在 xml 配置文件里 bean 标签指定构造器参数的类型,据此确定依赖注入的类型。 ~~~ <bean id="provider" class="com.apress.prospring5.ch3.xml.ConfigurableMessageProvider" c:message="I hope that someone gets my message in a bottle"/> <bean id="constructorConfusion" class="com.apress.prospring5.ch3.xml.ConstructorConfusion"> <constructor-arg type="int"> <value>90</value> </constructor-arg> </bean> ~~~