通常在 Spring 的 XML 中配置 bean 的方式有三种。
- 反射模式
- 工厂方法模式
- FactoryBean 模式
其中反射模式,用的是 bean 的全类名,也就是常用的配置方式,如下方式
<bean id="person" class="com.test.helloworld.Person">
<property name="name" value="小明"></property>
<property name="age" value="20"></property>
</bean>
下面介绍其他两种模式。
工厂模式
静态工厂
当调用静态方式方法创建 bean 是将对象的创建的过程封装到静态方法中,当客户端需要对象是,只需要简单的调用静态方法,而不关系对象创建的细节。下面是工厂类的代码
步骤一:创建工厂类和实体类
StaticFactory.java
public class StaticFactory {
private static Map<String,Person> persons = new HashMap<>();
static {
persons.put("小张", new Person("张","18"));
persons.put("小李", new Person("李","28"));
persons.put("小花", new Person("花","08"));
}
// 通过 key 获得值
public static Person getPerson(String key) {
return persons.get(key);
}
}
Person.java
public class Person {
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public Person() {
System.out.println("无参构造函数");
}
public Person(String name, String age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
步骤二:配置 XML
XML 配置
<bean class="com.test.helloworld.StaticFactory" id="person" factory-method="getPerson">
<constructor-arg value="小张"></constructor-arg>
</bean>
要声明通过静态方式创建,bean,需要在bean 的 class 属性中指拥有该工厂的方式的类,同时在 factory-method 属性中,指定工厂方法名称, 最后使用 constructor-arg 元素为方法传递参数。
- id:配置的bean实际上就是我们要获取的bean
- class:注意配置的不是要获取的 bean 的全类名,而是工厂方式的全类名
- factory-method:配置的是静态工厂方法名称,即获取 bean 的方法名称
- constructor-arg:如果静态工厂方法有入参,则使用此标签传递
步骤三:测试
测试类
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext2.xml");
Person person = (Person)applicationContext.getBean("person");
System.out.println(person);
}
实例工厂
通过实例工厂方法创建 bean,是将对象的创建过程封装到另外一个对象的实例,构造方法方法中去,当客户需要请求对象时,只需要简单的配置实例方法而不用去关心对象创建的细节。
步骤一:创建工厂类和实体类
InstanceFactory.java
public class InstanceFactory {
private Person person ;
public InstanceFactory() {
person = new Person("小天","20");
}
// 通过 key 获得值
public Person getPerson() {
return person;
}
}
Person.java
public class Person {
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public Person() {
System.out.println("无参构造函数");
}
public Person(String name, String age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
步骤二:配置 XML
XML 配置
<bean class="com.test.helloworld.InstanceFactory" id="InstanceFactory" >
</bean>
<bean class="com.test.helloworld.Person" id="person2" factory-method="getPerson" factory-bean="InstanceFactory">
</bean>
实例工厂本身是需要配置到IOC容器中
- factory-bean : 引用实例工厂的bean
- factory-method:配置的是实例工厂中获取bean的方法名称
- constructor-arg:如果实例工厂方法中获取bean的名称的方法有参数,则使用此标签传递
步骤三:测试
测试类
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext2.xml");
Person person = (Person)applicationContext.getBean("person2");
System.out.println(person);
}
FactoryBean 模式
Spring中有两种类型的bean,一种就是普通bean,另外一种就是工厂bean,即 FactoryBean
工厂Bean跟普通Bean不同,其返回的对象不是指定类的一个实例,其返回的是该工厂 Bean的getObject() 方法所返回的对象
步骤一:创建 FactoryBean 的实现类,目前我们需要管理的Bean的类型是Person,所以要指定泛型为 Person
PersonFactoryBean.java
public class PersonFactoryBean implements FactoryBean<Person>{
@Override
public Person getObject() throws Exception {
// TODO Auto-generated method stub
return new Person("小六","22");
}
@Override
public Class<?> getObjectType() {
// TODO Auto-generated method stub
return Person.class;
}
}
Person.java
public class Person {
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public Person() {
System.out.println("无参构造函数");
}
public Person(String name, String age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
步骤二:配置 XML
XML 配置
<bean id="person3" class="com.test.helloworld.PersonFactoryBean"></bean>
这里只需要配置这个工厂就行,当使用这个工厂的时候,会调用我们重写的 getObject()
方法。
步骤三:测试
测试类
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext2.xml");
Person person = (Person)applicationContext.getBean("person3");
System.out.println(person);
}