我还是以一个小项目来进行介绍。创建一个普通的java项目,也是和HelloWorld中创建的项目一样。这里主要涉及Person.java就是一个普通的Bean类,FactoryBeanImpl.java、InstanceFactory.java、StaticFactory.java这三个就是我们将要使用的工厂类,MainTest.java测试类,spring.xml容器的配置文件。他们的完整代码见下方。
一、静态工厂创建Bean实例
在StaticFactory.java工厂类中,主要有一个静态的Map变量persons,一个静态代码块static{},以及一个静态的方法getPerson(详细见下面的类代码)。我们结合配置文件来看,person这个bean的class是指向StaticFactory类,而factory-method属性指向的是getPerson(String name)方法,方法的入参是通过constructor-arg来注入的。这样通过配置文件与静态类的一一对应,在测试类中就可以获取到person的实例。在这里是所以使用map这个变量,就是说我还可以更具名称去返回多个不同的Bean,只要我在static代码块中put进去你需要的Person即可。
<bean id="person" class="com.escore.factories.StaticFactory"
factory-method="getPerson">
<constructor-arg value="suiwu"></constructor-arg>
</bean>
二、实例工厂创建Bean实例
在InstanceFactory.java类中内容基本与静态工厂的一样,只是去掉了static修饰符。那么我在结合类代码和配置文件来看,首先实例工厂需要配置一个自己的Bean(也就是实例工厂首先要实例化自己),然后在配置person2这个bean的内容。这里我们不再需要class属性,而是换成factory-bean属性来指向实例工厂Bean的id,他的工厂方法和参数注入与静态类的还是一样就不再说明。
<bean id="instanceFactory" class="com.escore.factories.InstanceFactory"></bean>
<bean id="person2"
factory-bean="instanceFactory"
factory-method="getPerson">
<constructor-arg value="wj"></constructor-arg>
</bean>
三、通过实现Spring提供的FactoryBean接口来创建Bean实例
在FactoryBeanImpl.java类中我实现了FactoryBean接口。该接口提供了三个必须实现的方法:getObject()返回对应Bean实例,getObjectType()返回对应Bean的类型,isSingleton()设置是否使用单例来创建Bean。在这个类中还添加了一个name变量和它对应的setter风格的方法,只是为了方便灵活配置Bean的name属性。下面来看他的配置方式,只需要将class指向该类就行,至于name属性是额外加上去的。
你可以将isSingleton()返回值设为true和false,试试在测试类中获取两次person3对象看看他们的引用是否指向的同一个对象。
<bean id="person3" class="com.escore.factories.FactoryBeanImpl">
<property name="name" value="王守仁"></property>
</bean>
Person.java完整代码
public class Person {
private String name;
public Person() {
super();
}
public Person(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person [name=" + name + "]";
}
}
StaticFactory.java类完整代码
import java.util.HashMap;
import java.util.Map;
import com.escore.beans.Person;
/**
* 静态工厂类
*/
public class StaticFactory {
private static Map<String, Person> persons = new HashMap<String,Person>();
static{
persons.put("suiwu", new Person("孙武"));
}
public static Person getPerson(String name){
return persons.get(name);
}
}
InstanceFactory.java类完整代码
import java.util.HashMap;
import java.util.Map;
import com.escore.beans.Person;
/**
* 实例工厂类
*/
public class InstanceFactory {
private Map<String, Person> persons = new HashMap<String,Person>();
{
persons.put("wj", new Person("王翦"));
}
public Person getPerson(String name){
return persons.get(name);
}
}
FactoryBeanImpl.java类完整代码
import org.springframework.beans.factory.FactoryBean;
import com.escore.beans.Person;
public class FactoryBeanImpl implements FactoryBean<Person>{
private String name;
public void setName(String name) {
this.name = name;
}
//返回Bean的实例
@Override
public Person getObject() throws Exception {
return new Person(name);
}
//返回Bean的类型
@Override
public Class<?> getObjectType() {
return Person.class;
}
//设置是否为单例模式。true表示是单例,false表示不是单例
@Override
public boolean isSingleton() {
return false;
}
}
MainTest.java类完整代码
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.escore.beans.Person;
public class MainTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
Person person = (Person) ctx.getBean("person3");
System.out.println(person);
ctx.close();
}
}
spring.xml配置文件完整代码
<?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.xsd">
<!-- 静态工厂配置
factory-method:是静态工厂返回Bean的方法,该方法的入参要用constructor-arg配置。
-->
<bean id="person" class="com.escore.factories.StaticFactory"
factory-method="getPerson">
<constructor-arg value="suiwu"></constructor-arg>
</bean>
<!-- 实例工厂
1,先配置实例工厂本身。
2,在需要使用的地方用factory-bean引用。(其它和静态工厂一样)
-->
<bean id="instanceFactory" class="com.escore.factories.InstanceFactory"></bean>
<bean id="person2"
factory-bean="instanceFactory"
factory-method="getPerson">
<constructor-arg value="wj"></constructor-arg>
</bean>
<!-- 通过实现FactoryBean接口来实现工厂创建Bean的实例 -->
<bean id="person3" class="com.escore.factories.FactoryBeanImpl">
<property name="name" value="王守仁"></property>
</bean>
</beans>