为什么需要使用自动装配
在通过XML配置文件进行设置Bean元素注入与声明注册后,我们能够发现一个问题,在项目中是会存在大量对象的,不可能全部都写在XML文件中,那会显得非常的臃肿,不利于后期维护,所以需要用到Spring的自动装配。
当然它依旧需要编写XML文件进行Bean的声明,但是它能够省去注入数据的步骤。
自动装配的模式
- no: 默认配置,即无自动配置,使用显式bean装配
- byName: 由属性名自动装配,扫描属性名,尝试同名bean与属性项连接
- byType: 由属性数据类型自动装配,扫描数据类型,尝试与确切的bean的注入属性相连接,若有多个bean,则会报错
- constructor: 类似于byType,适用于带有构造函数参数类型的bean
自动装配的局限性
- 重写的可能性:可以通过重写自动装配的注入关系设置指定依赖关系
- 原始数据类型:不能自动装配基本类型,字符串和类
- 混乱的本质:不精准的装配
1、byName自动装配
Product.java
public class Product {
private String pid;
private String pname;
public Product() {
}
public Product(String pid, String pname) {
this.pid = pid;
this.pname = pname;
}
public String getPid() {
return pid;
}
public void setPid(String pid) {
this.pid = pid;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
@Override
public String toString() {
return "Product{" +
"pid='" + pid + '\'' +
", pname='" + pname + '\'' +
'}';
}
}
Sales.java
public class Sales {
private String sid;
private int price;
private Product product;
public Sales(String sid, int price, Product product) {
this.sid = sid;
this.price = price;
this.product = product;
}
public Sales() {
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
@Override
public String toString() {
return "Sales{" +
"sid='" + sid + '\'' +
", price=" + price +
", product=" + product +
'}';
}
}
Beans.xml
Sales的setProduct(Product product)
当autowire=byName时,扫描到一个bean,id=product,将该bean数据注入Sales的product属性
注意:如果bean设置name有多个,且存在同name的bean存在,则会报异常,因为Spring比较笨,搞不清楚哪个匹配到的。
<bean id="sales" class="org.example.POJO.Sales" autowire="byName">
<property name="price" value="251"/>
<property name="sid" value="sales100000"/>
</bean>
<bean id="product" class="org.example.POJO.Product">
<property name="pid" value="p1233323"/>
<property name="pname" value="经典牛奶"/>
</bean>
Main.java
public class Main {
public static void main(String[] args) {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
Sales sales = (Sales) context.getBean("sales");
System.out.println(sales);
}
}
输出结果
Sales{sid='sales100000', price=251, product=Product{pid='p1233323', pname='经典牛奶'}}
2、byType自动装配
Beans.xml
setProduct(Product product)
当autowire=byType时,扫描到一个bean,class=org.example.POJO.Product,将该bean数据注入Sales的product属性
注意:如果bean设置name有多个,且存在同class的bean存在,则会报异常,因为Spring比较傻,搞不清楚哪个匹配到的。
<bean id="sales" class="org.example.POJO.Sales" autowire="byType">
<property name="price" value="251"/>
<property name="sid" value="sales100000"/>
</bean>
<bean id="product" class="org.example.POJO.Product">
<property name="pid" value="p1233323"/>
<property name="pname" value="经典牛奶"/>
</bean>
3、constructor自动装配
Beans.xml
public Sales(String sid, int price, Product product)
当autowire=constructor时,扫描到一个bean,class=org.example.POJO.Product,将该bean数据注入Sales的product属性,可以按照byType的规则进行使用
注意:如果bean设置name有多个,且存在同class的bean存在,则会报异常,因为Spring比较傻,搞不清楚哪个匹配到的。
<bean id="sales" class="org.example.POJO.Sales" autowire="constructor">
<constructor-arg name="price" value="251"/>
<constructor-arg name="sid" value="sales100000"/>
</bean>
<bean id="product" class="org.example.POJO.Product">
<property name="pid" value="p1233323"/>
<property name="pname" value="经典牛奶"/>
</bean>