提到Bean的加载,就不得不提一下依赖注入的问题。
Spring提供4中依赖注入的方法:set注入,构造器注入,静态工厂注入,实例工厂注入。
现有实体类Dog,有1个String属性dogName,还是有setter和getter方法,空参构造器和有参构造器,类的结构如下:
public class Dog {
private String dogName;
public void setDogName(String dogName) {
System.out.println("setDogName()生效了!");
this.dogName = dogName;
}
public String getDogName() {
return dogName;
}
public Dog(){
System.out.println("Dog()生效了!");
}
public Dog(String dogName){
System.out.println("Dog(String dogName)生效了!");
this.dogName = dogName;
}
}
1.set注入
这也是我们用的最多的注入方式,我们可以在xml文件中作出以下配置:
<bean id="dog" class="com.kk.t.Dog">
<property name="dogName" value="dahuang" ></property>
</bean>
通过Spring的ApplicationContext容器获取Dog对象时,控制台打印如下:
Dog()生效了!
setDogName()生效了!
可见,Spring在创建对象的实例时,也是首先调用对象的无参构造器,然后调用对应属性的set方法进入注入。
2.构造器注入
顾名思义,是指使用对象的构造器进行对象的实例化,我们可以在xml中进行如下配置;
然后启动程序,控制台打印如下:
Dog(String dogName)生效了!
可见此时Spring选择的是含参数的构造方法进行的实例化。
值得注意的是:对于参数个数相同的构造器,我们需要在xml中指定参数的类型,避免Spring调用与我们本意不符的构造器以引起不必要的争议。
3.静态工厂注入
静态工厂即使用工厂模式,我们把工厂bean也交给Spring托管,再暴露出bean工厂的某一方法,从方法中获取我们需要的bean,说起来有点拗口,直接看代码。
Dog还是那个Dog,现在我们再写一个类DogSeller(卖狗的),之前我们获取狗是自己去new,现在我们从卖狗的那去买,DogSeller结构如下:
public class DogSeller {
public static Dog getDog() {
return new Dog();
}
}
简单明了,我们可以通过getDog()来获取一个Dog实例,但此时是要交给Spring来管理的,所以xml代码如下:
<bean id="dogFactory" class="com.kk.t.DogSeller" factory-method="getDog"></bean>
现在我们在运行之前的代码,注意(要把getBean后的id换成这个bean的id),成功得到Dog对象,因为我们在getDog中调用的是空构造器所以dogName == null。
4.实例工厂注入
实例工厂和静态工厂的区别在于实例工厂的方法是非静态的方法,此时我们就不能在工厂bean中调用,xml配置如下:
<bean id="dogFactory" class="com.kk.t.DogSeller"/>
<bean id="myDog" factory-bean="dogFactory" factory-method="getDog"/>
控制台打印结果与之前相同!