Spring框架中的BeanFactory接口和FactoryBean接口因为名称相似,老是容易搞混淆,而且也是面试过程中经常会碰到的一个问题。所以本文就专门给大家整理出来。
一、BeanFactory接口 BeanFactory接口是Spring容器的核心接口,负责:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
Spring为我们提供了许多易用的BeanFactory实现,XmlBeanFactory就是常用的一个,该实现将以XML方式描述组成应用的对象及对象间的依赖关系。XmlBeanFactory类将持有此XML配置元数据,并用它来构建一个完全可配置的系统或应用。
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
Object bean = bf.getBean(IUserService.class);
System.out.println(bean);接口中定义的方法
public interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&"; Object getBean(String name) throws BeansException;
T getBean(String name, Class requiredType) throws BeansException; Object getBean(String name, Object... args) throws BeansException;
T getBean(Class requiredType) throws BeansException;
T getBean(Class requiredType, Object... args) throws BeansException; boolean containsBean(String name); boolean isSingleton(String name) throws NoSuchBeanDefinitionException; boolean isPrototype(String name) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String name, Class> typeToMatch) throws NoSuchBeanDefinitionException;
Class> getType(String name) throws NoSuchBeanDefinitionException;
String[] getAliases(String name);
} 二、FactoryBean接口BeanFactory接口是Spring的核心接口。功能非常复杂,这个时候如果我们想要编写一些比较复杂点儿的逻辑就会触及到其他一些不必要的接口,不好实现。这时候使用FactoryBean就比较方便了。FactoryBean以Bean结尾是个Bean对象,不是工厂。接口中定义的方法如下:
public interface FactoryBean1.简单实现{ T getObject() throws Exception; Class> getObjectType(); boolean isSingleton(); }
接口和实现类
public interface IUserService { public void doSome();
}public class UserServiceImpl implements IUserService {
public UserServiceImpl(){
System.out.println("--被实例化了--");
} @Override
public void doSome() {
System.out.println("UserServiceImpl 。。。 被执行了");
}
}自定义FactoryBean
public class MyFactoryBean implements FactoryBean{ @Override public IUserService getObject() throws Exception { System.out.println("--IUserService实例化之前---"); IUserService service = new UserServiceImpl(); System.out.println("--IUserService实例化后---"); return service; } @Override public Class> getObjectType() { return IUserService.class; } @Override public boolean isSingleton() { return true; } }
配置文件
测试--通过类型获取
@Testpublic void test1() {
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
Object bean = bf.getBean(IUserService.class);
System.out.println(bean);
}输出结果
--IUserService实例化之前--- --被实例化了-- --IUserService实例化后--- com.dpb.service.UserServiceImpl@5315b42e
测试--通过id获取
@Testpublic void test1() {
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
Object bean = bf.getBean("myFactoryBean");
System.out.println(bean);
}输出结果
--IUserService实例化之前--- --被实例化了-- --IUserService实例化后--- com.dpb.service.UserServiceImpl@783e6358
如果想要获取FactoryBean对象 id前加 &就可以
@Testpublic void test1() {
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
Object bean = bf.getBean("&myFactoryBean");
System.out.println(bean);
}输出结果
com.dpb.factorybean.MyFactoryBean@3b81a1bc2.增强实现
通过FactoryBean创建一个代理类来增强目标类,我们来看下效果
接口和实现类
public interface IUserService { public void doSome();
}public class UserServiceImpl implements IUserService {
public UserServiceImpl(){
System.out.println("--被实例化了--");
} @Override
public void doSome() {
System.out.println("UserServiceImpl 。。。 被执行了");
}
}自定义FactoryBean
public class MyFactoryBean implements FactoryBean,InitializingBean,DisposableBean{
private Object proxyObject;
private Object target;
private String interfaceName; @Override
public Object getObject() throws Exception {
return proxyObject;
} @Override
public Class> getObjectType() { return proxyObject.getClass()==null?Object.class:proxyObject.getClass();
} @Override
public boolean isSingleton() { return true;
}
@Override
public void destroy() throws Exception {
System.out.println("destroy ....");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("---afterPropertiesSet---");
proxyObject = Proxy.newProxyInstance( this.getClass().getClassLoader()
, new Class[]{Class.forName(interfaceName)}
, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("----代理方法执行开始----");
Object obj = method.invoke(target, args);
System.out.println("----代理方法执行结束----"); return obj;
}
});
} public String getInterfaceName() { return interfaceName;
} public void setInterfaceName(String interfaceName) { this.interfaceName = interfaceName;
} public Object getTarget() { return target;
} public void setTarget(Object target) { this.target = target;
}
}配置文件
测试
@Testpublic void test1() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
IUserService bean = (IUserService) ac.getBean("myFactoryBean");
System.out.println("****************");
bean.doSome();
System.out.println();
}输出结果:
--被实例化了-- ---afterPropertiesSet--- **************** ----代理方法执行开始---- UserServiceImpl 。。。 被执行了 ----代理方法执行结束----
小结:通过输出结果我们可以看到通过FactoryBean接口我们也可以实现BeanFactory中某些接口提供的功能,而且会更加的灵活一些。
3.FactoryBean的实际使用案例Spring在整合mybatis框架的时候提供的SqlSessionFactoryBean就是FactoryBean的很好的实现。
getObjectType() { return this.sqlSessionFactory == null ? SqlSessionFactory.class : this.sqlSessionFactory.getClass(); } @Override public boolean isSingleton() { return true; }
maven坐标:
三、总结org.mybatis mybatis-spring1.3.2
BeanFactory是Spring中IOC容器最核心的接口,遵循了IOC容器中所需的基本接口。例如我们很常见的:ApplicationContext,XmlBeanFactory 等等都使用了BeanFactory这个接口。
FactoryBean是工厂类接口,当你只是想简单的去构造Bean,不希望实现原有大量的方法。它是一个Bean,不过这个Bean能够做为工厂去创建Bean,同时还能修饰对象的生成。
FactoryBean比BeanFactory在生产Bean的时候灵活,还能修饰对象,带有工厂模式和装饰模式的意思在里面,不过它的存在还是以Bean的形式存在。
作者:ゞ .邓澎波
原文出处:https://www.cnblogs.com/dengpengbo/p/10493782.html



