转载自: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提供的方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| public interface BeanFactory { String FACTORY_BEAN_PREFIX = "&"; Object getBean(String name) throws BeansException; <T> T getBean(String name, Class<T> requiredType) throws BeansException; <T> T getBean(Class<T> 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过程比较复杂,如果按照传统的方式,则需要在<bean>中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。
Spring为此提供了org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。
以Bean结尾,表示它是一个Bean,不同于普通Bean的是:它是实现了FactoryBean<T>接口的Bean,根据该Bean的ID从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身,如果要获取FactoryBean对象,请在id前面加一个&符号来获取。
例如实现一个FactoryBean,功能:用来代理一个对象,对该对象的所有方法做一个拦截,在调用前后都输出一行LOG,模仿ProxyFactoryBean的功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| /** * 代理一个类,拦截该类的所有方法,在方法的调用前后进行日志的输出 */ public class MyFactoryBean implements FactoryBean<Object>, 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配置如下
1 2 3 4
| <bean id="fbHelloWorldService" class="com.ebao.xxx.MyFactoryBean"> <property name="interfaceName" value="com.ebao.xxx.HelloWorldService" /> <property name="target" ref="helloWorldService" /> </bean>
|