Spring的依赖注入冲突
学习到Spring的自动依赖注入时,突然想到<Bean>的autowire="constructor"时,如果有多个构造器满足注入的条件时会发生什么。我在CSDN一篇关于自动注入的博客找到了相关的解释Spring自动注入详解 (转载,不知道原创出处)。但进而考虑到byName和byType会不会也有冲突的问题呢?
一、constructor 自动依赖注入冲突
当有多个构造器可以注入时:
- 先按修饰符排序,public优先
- 再按参数个数排序,参数多的优先
- 构造器参数相同,但参数的顺序不同时,写在前面的优先 参考:Spring常用的三种注入方式
public class User { private int id; private int age; private String name; private Person person; public User() { } public User(int id, int age, String name) { this.id = id; this.age = age; this.name = name; } public User(Person person) { System.out.println("constructor_1: person"); this.id = person.getId(); this.age = person.getAge(); this.name = person.getName(); this.person = person; } public User(Person person, int id) { System.out.println("constructor_2: person id"); this.id = id; this.age = person.getAge(); this.name = person.getName(); this.person = person; } //各参数的getter和setter方法,重写的toString方法 }
<bean id="person" class="pojo.Person" p:id="2" p:age="22" p:name="person"/> <bean id="user1" name="user" class="pojo.User" autowire="constructor"/> <bean id="user2" name="user" class="pojo.User" autowire="constructor" c:id="5"/>
public class Main { public static void main(String[] args) { AbstractApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); User user1 =(User) app.getBean("user1"); User user2 =(User) app.getBean("user2"); System.out.println(user1); System.out.println(user2); } }
运行结果:

二、byName 和 byType 重载set方法冲突
ps:没有找到相关的资料,仅为个人的尝试和思考。
如果出现了set方法的重载,Spring如何选择set方法。
- setAge(int age){};
- setAge(Integer age){};
下面分类讨论通过set的自动注入的模式:
1、byName :根据BeanID去匹配set的属性名
如果重载setAge方法冲突,则需要有多个相同ID的Bean,故冲突转移到了BeanID的冲突上。
2、byType :根据set的参数类型去匹配Bean。
方法的重载需要参数列表不同
- 单参数set方法:
下面是Human类和Person类,两个类基本相同,并提供了互相转换的toPerson()和toHuman方法
package pojo; public class Person { private int id; private int age; private String name; public Person(){ } public Person(int id, int age, String name){ this.id = id; this.age = age; this.name = name; } public Human toHuman(){ Human human = new Human(); human.setId(this.id); human.setAge(this.age); human.setName(this.name); return human; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return id + " " + age + " " + name; } }
public class Human { private int id; private int age; private String name; public Human(){ } public Human(int id, int age, String name){ this.id = id; this.age = age; this.name = name; } public Person toPerson(){ Person pserson = new Person(); pserson.setId(this.id); pserson.setAge(this.age); pserson.setName(this.name); return pserson; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return id + " " + age + " " + name; } }
User类,可以通过set方法接收Human和Person进行初始化。重载了setHuman()和setPerson()
public class User { private int id; private int age; private String name; private Person person; private Human human; public User() { } public User(int id, int age, String name) { this.id = id; this.age = age; this.name = name; } public Person getPerson() { return person; } public Human getHuman() { return human; } public void setHuman(Human human) { System.out.println("名参相同:setHuman human"); this.human = human; this.person = human.toPerson(); this.id = human.getId(); this.age = human.getAge(); this.name = human.getName(); } public void setHuman(Person person) { System.out.println("名参不同:setHuman person"); this.person = person; this.human = person.toHuman(); this.id = person.getId(); this.age = person.getAge(); this.name = person.getName(); } public void setPerson(Person person) { System.out.println("名参相同:setPerson person"); this.person = person; this.human = person.toHuman(); this.id = person.getId(); this.age = person.getAge(); this.name = person.getName(); } public void setPerson(Human human) { System.out.println("名参不同:setPerson human"); this.human = human; this.person = human.toPerson(); this.id = human.getId(); this.age = human.getAge(); this.name = human.getName(); } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return id + " " + age + " " + name; } }
没有发现直观的规律,最终的值取决于Spring执行set注入的顺序
运行结果:

- 多参数set方法:
多参数的set方法不符合标准JavaBean的定义
三、同时有构造注入和set注入的冲突
先进行构造注入,再进行set注入。毕竟得先用构造器创建对象,才能调用它的实例方法。
参考文章:set注入和构造注入顺序
<bean id="person" class="pojo.Person" c:id="2" c:age="22" c:name="构造注入"> <property name="name" value="set注入"/> </bean>
运行结果:
![]()
如果有错误或需要补充的内容,请评论告诉我,谢谢!

浙公网安备 33010602011771号