FactoryBean的用法
在某些情况下,实例化bean过程比较复杂,如果还是采用配置的方法,
需要在中提供大量的配置信息,配置方式的灵活性是受限的,
这时采用编码的方式可能会得到一个简单的方案。
Spring为此提供了一个FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化bean的逻辑。
public interface FactoryBean<T> {
T getObject() throws Exception;
Class<?> getObjectType();
boolean isSingleton();
}
- T getObject()
返回由FactoryBean创建的bean实例,如果isSingleton()返回true,则该实例会放到Spring容器中单实例缓存池中。 - boolean isSingleton():
返回由FactoryBean创建的bean实例的作用域是是不是singleton - Class getObjectType()
返回FactoryBean创建的bean类型。
Spring通过反射机制发现xxxx类实现了FactoryBean的接口,这时Spring容器就调用接口方法getObject()方法返回。
如果希望获取xxxx类的实例,则需要在使用getBean(beanName) 方法时在beanName前显示的加上 “&” 前缀
例子
public class Student {
private String name;
private Integer age;
}
public class MyFactoryBean implements FactoryBean<Student> {
private volatile Student student = null;
@Override
public Student getObject() throws Exception {
System.out.println("Student被创建");
if (student == null) {
synchronized (MyFactoryBean.class) {
if (student == null) {
student = new Student("student",22);
}
}
}
return student;
}
@Override
public Class<?> getObjectType() {
return Student.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
配置文件
<bean id="student" class="com.xxx.entity.MyFactoryBean">
</bean>
public static void main( String[] args ) {
ApplicationContext app = new ClassPathXmlApplicationContext("SpringConfig.xml");
Student student = app.getBean("student",Student.class);
System.out.println(student);
}
控制态输出
Student被创建
Student{name=‘student’, age=22}
当调用getBean(“student”) 时,Spring通过反射机制发现MyFactoryBean实现了FactoryBean的接口,这时Spring容器就调用接口方法MyFactoryBean的getObject()方法返回。
如果希望获取MyFactoryBean的实例,则需要在使用getBean(beanName) 方法时在beanName前显示的加上 “&” 前缀,例如getBean("&student")。