Bean的注入方式
什么是Bean?
Spring里面的bean就类似是定义的一个组件,而这个组件的作用就是实现某个功能的,在spring里给定义的bean就是说,我给你了一个更为简便的方法来调用这个组件去实现你要完成的功能。
Bean 的依赖注入
这里介绍两种注入方式:构造注入与属性注入,至于工厂方法不提倡,这里不介绍
构造注入
构造函数注入是除属性注入之外的另一种常用的注入方式,它可以保证一些必要的属性在bean实例化时就得到了设置,并在实例化后就可以使用。
使用构造函数注入的前提是:bean必须提供带参的构造函数。
实例:
有一个book类:
public class Book {
private String bookname;
private Integer isbn;
private Double price;
@Override
public String toString() {
return "Book1{" +
"bookname='" + bookname + '\'' +
", isbn=" + isbn +
", price=" + price +
'}';
}
上面说到属性注入要有一个构造方法,在上面的类中添加一个带参构造函数:
/**
* 1.使用构造注入
* 1.1提供带所有参数的有参构造方法。
*/
public Book(String bookname, Integer isbn, Double price) {
this.bookname = bookname;
this.isbn = isbn;
this.price = price;
}
编写bean的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<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-4.3.xsd">
<bean id="bean1" class="instance.assemble.Book">
<!--1.使用构造注入方式装配Book实例 -->
<constructor-arg index="0" value="Vue" />
<constructor-arg index="1" value="1234" />
<constructor-arg index="2" value="45.9"/>
</bean>
</beans>
属性注入
属性注入即通过setXXX()方法注入Bean的属性值或者依赖对象,由于属性注入方式具有可选择性和灵活高的优点,因此属性注入是实际中最常采用的注入方式。
Spring首先会调用bean的默认构造函数实例化bean对象,然后再通过反射的方法来调用set方法来注入属性值。
属性注入要求bean提供一个默认的构造函数,并且得为需要注入的属性提供set方法。
注意:所谓默认构造函数是指不带参的构造函数
实例:
在上面的Book类中添加默认构造函数,并且设置set方法
/**
* 2.使用设值注入
* 2.1提供默认空参构造方法 ;
* 2.2为所有属性提供setter方法。
*/
public Book() {
}
public void setBookname(String bookname) {
this.bookname = bookname;
}
public void setIsbn(Integer isbn) {
this.isbn = isbn;
}
public void setPrice(Double price) {
this.price = price;
}
- 配置bean文件,在上面的文件中添加一个bean
<!--2.使用set注入方式装配Book实例 -->
<bean id="bean2" class="instance.assemble.Book">
<property name="bookname" value="Vue"></property>
<property name="isbn" value="123456"></property>
<!-- 注入list集合 -->
<property name="price" value="46.8"></property>
</bean>
为上面两种方式编写一个测试类,实例化两个bean,打印出两个Book实例
public class InstanceTest {
public static void main(String[] args) {
// 定义配置文件路径
String xmlPath = "instance/assemble/beans.xml";
// ApplicationContext在加载配置文件时,对Bean进行实例化
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext(xmlPath);
Book book1 = (Book) applicationContext.getBean("bean1");
Book book2 = (Book) applicationContext.getBean("bean2");
System.out.println(book1);
System.out.println(book2);
}
}
结果:
总结:
Spring提供了三种可供选择的注入方式,但在实际应用中,我们究竟该选择哪种注入方式,并没有统一的标准,如下是一些可以参考的理由:
构造函数注入理由:
● 构造函数保证重要属性预先设置;
● 无需提供每个属性的setter方法,减少类的方法个数;
● 可以更好地封装类变量,避免外部错误调用。
属性注入理由:
● 属性过多时,构造函数变的臃肿;
● 构造函数注入灵活性不强,有时需要为属性注入null值;
● 多个构造函数时,配置上产生歧义,复杂度升高;
● 构造函数不利于类的继承和扩展;
● 构造函数注入会引起循环依赖的问题。
参考链接: Spring中的bean注入方式