Spring BeanFactory 与 FactoryBean的区别

首先总结一下BeanFactory 与 FactoryBean 的区别

BeanFactroy spring中Bean的工厂,它能够去生产我们的类,并且能够获取我们的对象,比如我们的一个类交给spring去管理,我们可以通过这个BeanFactroy 直接get BeanName出来。

FactroyBean,它是spring中一个特殊的Bean,它是一个接口里面有三个方法需要去实现,实现了FactroyBean的Bean可以再去创建一个Bean,就是getObject()这个方法实际返回的Bean,

他们存在spring容器中的形式也不一样,如果需要get到 实现了FactroyBean的Bean,需要再BeanName前面加一个‘&’ 符号去得到。如果需要得到getObject()这个方法实际返回的Bean 直接get BeanName

下面我们看代码来实现

我们先来一个普通的对象如下

package org.springframework.test.main.entity;

public class Student {

	public void query(){
		System.out.println("org.springframework.test.main.entity.Student.query");
	}

}

再来一个spring管理的类,这儿使用注解的方式来做

package org.springframework.test.main.entity;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;

@Component
public class Parent implements FactoryBean {
	@Override
	public Object getObject() throws Exception {
		return new Student();
	}

	@Override
	public Class<?> getObjectType() {
		return Student.class;
	}

	@Override
	public boolean isSingleton() {
		return true;
	}

	public void query(){
		System.out.println("org.springframework.test.main.entity.Parent.query");
	}
}

再来测试类

package org.springframework.test.main;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.main.config.ScanConfig;
import org.springframework.test.main.entity.Parent;
import org.springframework.test.main.entity.Student;

public class MainDemo {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(ScanConfig.class);
		Parent parent =(Parent) ac.getBean("parent");
		parent.query();
	}

}

我们着重来看getBean的这行代码,正常情况下,如果我们的parent没有实现FactoryBean这个接口是可以调用parent中query()方法的。

但是如果一旦实现了FactoryBean这个接口重写了里面的getObject()方法,这个方法返回的bean是最终获取的Bean
有了这个结论,运行以上代码很显然会报错,我们看到了类型转换异常
 

D:\java\jdk8\bin\java.exe "
Exception in thread "main" java.lang.ClassCastException: org.springframework.test.main.entity.Student cannot be cast to org.springframework.test.main.entity.Parent
	at org.springframework.test.main.MainDemo.main(MainDemo.java:12)

Process finished with exit code 1

我们来改一下,我们在getBean("&parent");加上&符号在运行会发现成功调用了parent中query()方法

我们再回到上面的类型转换异常的问题,当我们将parent改成getObject()方法中返回的Student的时候,结果成功调用了Student的query()方法。即Student parent =(Student) ac.getBean("parent");

我们知道spring容器在启动的时候会将带有@Component注解的对象交给spring容器去管理,比如本文中的Parent,我们在获取的时候直接getBean("parent")是可以正常获取到的。但当我们的这个bean实现了FactoryBean这个接口重写了里面的一个getObject()的方法的话,在获取这个bean是需要加上getBean("&parent"),而我们getObject()方法返回的对象则可以直接getBean("parent")了。
比如文中的才是正常的了

Parent parent =(Parent) ac.getBean("&parent");//实现了FactoryBean的bean
Student parent =(Student) ac.getBean("parent");//实现了FactoryBean的bean重写的getObject()方法中返回的Bean

这个就很好的回答的上面的那个总结

最常见的应用场景就是Mybaits中的SqlSessionFactory对象。
 

猜你喜欢

转载自blog.csdn.net/qq_38108719/article/details/93489624