BeanFactory和FactoryBean

转载自:https://www.cnblogs.com/aspirant/p/9082858.html
?
??BeanFactory是个Factory,也就是IOC容器或对象工厂,FactoryBean是个Bean。
??在Spring中,所有的bean都是由BeanFactory(也就是IOC容器)来进行管理的。如XMLBeanFactory就是一种典型的BeanFactory。常用的ApplicationContext接口也是由BeanFactory接口派生而来,ApplicationContext包含BeanFactory的所有功能,通常建议比BeanFactory优先。
??对FactoryBean而言,这个bean不是简单的bean,而是一个能生产或者装饰对象生成的工厂bean,它为IOC容器中bean的实现提供了更加灵活的方式,可以在getObject()方法中灵活配置。
??
1、 BeanFactory
??BeanFactory负责生产和管理bean的一个工厂。在Spring中,BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。??BeanFactory只是个接口,并不是IOC容器的具体实现,但是Spring容器给出了很多种实现,如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等。
??可以通过BeanFactory获取IOC管理的bean,BeanFactory提供的方法如下:

public interface BeanFactory { String FACTORY_BEAN_PREFIX = "&"; Object getBean(String name) throws BeansException; T getBean(String name, Class requiredType) throws BeansException; T getBean(Class requiredType) throws BeansException; Object getBean(String name, Object... args) throws BeansException; boolean containsBean(String name); boolean isSingleton(String name) throws NoSuchBeanDefinitionException; boolean isPrototype(String name) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException; Class getType(String name) throws NoSuchBeanDefinitionException; String[] getAliases(String name); }

??
2、FactoryBean
??一般情况下,Spring通过反射机制实现类实例化Bean,在某些情况下,实例化Bean过程比较复杂,如果按照传统的方式,则需要在中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。
??Spring为此提供了org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。
??以Bean结尾,表示它是一个Bean,不同于普通Bean的是:它是实现了FactoryBean接口的Bean,根据该Bean的ID从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身,如果要获取FactoryBean对象,请在id前面加一个&符号来获取。
??例如实现一个FactoryBean,功能:用来代理一个对象,对该对象的所有方法做一个拦截,在调用前后都输出一行LOG,模仿ProxyFactoryBean的功能。
/** * 代理一个类,拦截该类的所有方法,在方法的调用前后进行日志的输出 */ public class MyFactoryBean implements FactoryBean, InitializingBean, DisposableBean {private static final Logger logger = LoggerFactory.getLogger(MyFactoryBean.class); private String interfaceName; private Object target; private Object proxyObj; @Override public void destroy() throws Exception { logger.debug("destroy......"); } @Override public void afterPropertiesSet() throws Exception { proxyObj = Proxy.newProxyInstance( this.getClass().getClassLoader(), new Class[] { Class.forName(interfaceName) }, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { logger.debug("invoke method......" + method.getName()); logger.debug("invoke method before......" + System.currentTimeMillis()); Object result = method.invoke(target, args); logger.debug("invoke method after......" + System.currentTimeMillis()); return result; } }); logger.debug("afterPropertiesSet......"); }@Override public Object getObject() throws Exception { logger.debug("getObject......"); return proxyObj; }@Override public Class getObjectType() { return proxyObj == null ? Object.class : proxyObj.getClass(); }@Override public boolean isSingleton() { return true; }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; }public Object getProxyObj() { return proxyObj; }public void setProxyObj(Object proxyObj) { this.proxyObj = proxyObj; }}
XML-Bean配置如下
【BeanFactory和FactoryBean】

    推荐阅读