一、FactoryBean示例
public class DateStringFactoryBean implements FactoryBean<Object> { private boolean isDate; public void setDate(boolean date) { isDate = date; } @Override public Object getObject() { return isDate ? new Date() : "2018-03-04"; } @Override public Class<?> getObjectType() { return isDate ? Date.class : String.class; } @Override public boolean isSingleton() { return false; } }
AppConfig
public class AppConfig { @Bean(name = "dateFactoryBean") public DateStringFactoryBean createString(){ DateStringFactoryBean bean = new DateStringFactoryBean(); bean.setDate(true); return bean; } @Bean(name = "stringFactoryBean") public DateStringFactoryBean createDate(){ DateStringFactoryBean bean = new DateStringFactoryBean(); bean.setDate(false); return bean; } }
Main
public class Main { public static void main(String[] args) { AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); System.out.println(context.getBean("dateFactoryBean", Date.class)); System.out.println(context.getBean("stringFactoryBean", String.class)); System.out.println(context.getBean("&dateFactoryBean")); //使用&+beanName获得DateStringFactoryBean实例 System.out.println(context.getBean("&stringFactoryBean")); } }
二、调试分析
1. 系统启动时,会注册FactoryBean
2. context.getBean("dateFactoryBean", Date.class) 时
三、相关文档
Bean factory implementations should support the standard bean lifecycle interfaces as far as possible. The full set of initialization methods and their standard order is:
- BeanNameAware's
setBeanName
- BeanClassLoaderAware's
setBeanClassLoader
- BeanFactoryAware's
setBeanFactory
- EnvironmentAware's
setEnvironment
- EmbeddedValueResolverAware's
setEmbeddedValueResolver
- ResourceLoaderAware's
setResourceLoader
(only applicable when running in an application context) - ApplicationEventPublisherAware's
setApplicationEventPublisher
(only applicable when running in an application context) - MessageSourceAware's
setMessageSource
(only applicable when running in an application context) - ApplicationContextAware's
setApplicationContext
(only applicable when running in an application context) - ServletContextAware's
setServletContext
(only applicable when running in a web application context) postProcessBeforeInitialization
methods of BeanPostProcessors- InitializingBean's
afterPropertiesSet
- a custom init-method definition
postProcessAfterInitialization
methods of BeanPostProcessors
BeanFactory 是 IOC 容器的编程抽象,比如 ApplicationContext, XmlBeanFactory 等,这些都是 IOC 容器的具体表现
FactoryBean 是一个可以在 IOC而容器中被管理的一个 bean,是对各种处理过程和资源使用的抽象,FactoryBean 在需要
时产生另一个对象,而不返回 FactoryBean本身,我们可以把它看成是一个抽象工厂,对它的调用返回的是工厂生产的产
品。Spring对代理对象的处理,对事务性代理的处理都使用了FactoryBean
public interface FactoryBean<T>
BeanFactory
which are themselves factories for individual objects.NB: A bean that implements this interface cannot be used as a normal bean. A FactoryBean is defined in a bean style,
but the object exposed for bean references (getObject()
) is always the object that it creates.
FactoryBeans can support singletons and prototypes, and can either create objects lazily on demand or eagerly on startup.
The SmartFactoryBean
interface allows for exposing more fine-grained behavioral metadata.
This interface is heavily used within the framework itself, for example for the AOP ProxyFactoryBean
.
It can be used for custom components as well; however, this is only common for infrastructure code.
FactoryBean
is a programmatic contract. Implementations are not supposed to rely on annotation-driven injection
or other reflective facilities. getObjectType()
getObject()
invocations may arrive early in the bootstrap process, even
ahead of any post-processor setup. If you need access other beans, implement BeanFactoryAware
and obtain them programmatically.
Finally, FactoryBean objects participate in the containing BeanFactory's synchronization of bean creation. There is usually no
need for internal synchronization other than for purposes of lazy initialization within the FactoryBean itself (or the like).
同类文章