Spring原始碼之FactoryBean的實現
https://zhuanlan.zhihu.com/p/97005407
https://blog.csdn.net/qq_35634181/article/details/104507465
總結
- FactoryBean的物件會先在createWebServer時,建立BeanWrapper,並放到factoryBeanInstanceCache快取中
- 在預例項化時,走FactoryBean邏輯,呼叫getBean去執行屬性注入、初始化過程(此時物件例項化直接從factoryBeanInstanceCache快取中取)
- 完成FactoryBean的實現類初始化
- 呼叫實現類的getObject方法,從而對工廠中類進行功能增強
FactoryBean(實現類)的初始化
初始化入口依然是AbstractApplicationContext#finishBeanFactoryInitialization() ,走到DefaultListableBeanFactory類preInstantiateSingletons方法時,和普通bean邏輯不同,執行以下程式碼:
@Override public void preInstantiateSingletons() throws BeansException { // Iterate over a copy to allow for init methods which in turn register new bean definitions. // While this may not be part of the regular factory bootstrap, it does otherwise work fine. List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { //FactoryBean的初始化執行入口 if (isFactoryBean(beanName)) { Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { FactoryBean<?> factory = (FactoryBean<?>) bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged( (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } } else { //普通bean的執行入口 getBean(beanName); } } } }
呼叫Object bean = getBean(FACTORY_BEAN_PREFIX + beanName),後面基本和普通bean的初始化一致
其中不同有:instanceWrapper不為null,是createWebServer時放入factoryBeanInstanceCache中的
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
將FactoryBean實現類放入快取呼叫鏈為:
SpringApplication#run() --> SpringApplication#refreshContext() --> SpringApplication#refresh() -->ServletWebServerApplicationContext#refresh() --> AbstractApplicationContext#refresh() --> AbstractApplicationContext#onRefresh() --> ServletWebServerApplicationContext#createWebServer() --> ServletWebServerApplicationContext#getWebServerFactory() --> DefaultListableBeanFactory#getBeanNamesForType() --> DefaultListableBeanFactory#doGetBeanNamesForType() --> AbstractBeanFactory#isTypeMatch() --> AbstractAutowireCapableBeanFactory#getTypeForFactoryBean() --> AbstractAutowireCapableBeanFactory#getSingletonFactoryBeanForTypeCheck()
mbd為:
// Generics potentially only match on the target class, not on the proxy...
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
bw為:
Object instance;
try {
// Mark this bean as currently in creation, even if just partially.
beforeSingletonCreation(beanName);
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
instance = resolveBeforeInstantiation(beanName, mbd);
if (instance == null) {
bw = createBeanInstance(beanName, mbd, null);
instance = bw.getWrappedInstance();
}
}
catch (BeanCreationException ex) {
......
}
finally {
// Finished partial creation of this bean.
afterSingletonCreation(beanName);
}
FactoryBean為:
FactoryBean<?> fb = getFactoryBean(beanName, instance);
if (bw != null) {
this.factoryBeanInstanceCache.put(beanName, bw);
}
獲取FactoryBean實現類(非工廠)的過程
如(此時beanName前面沒有&):
Object factoryBeanTest = context.getBean("factoryBeanTest");
會先在AbstractBeanFactory#doGetBean()中執行:
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
......
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
}
執行getObjectForBeanInstance方法:
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
......
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
呼叫getObjectFromFactoryBean,再呼叫doGetObjectFromFactoryBean方法:
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
//object為null
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
object = doGetObjectFromFactoryBean(factory, beanName);
......
}
}
}
}
最後呼叫實際FactoryBean實現類的getObject方法,完成工廠類的自定義功能增強
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
......
}
else {
//去執行實際實現類的getObject方法
object = factory.getObject();
}
}
return object;
}
通過FactoryBean.getObject方式
如:
FactoryBean bean = (FactoryBean)context.getBean("&factoryBeanTest");
CustomTask customTask = (CustomTask)bean.getObject();
會通過AbstractBeanFactory#doGetBean()直接返回bean
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// Eagerly check singleton cache for manually registered singletons.
//此時一級快取singletonObjects中有資料
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
......
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
呼叫getObjectForBeanInstance,返回beanInstance
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
//此時為true
if (BeanFactoryUtils.isFactoryDereference(name)) {
......
if (mbd != null) {
mbd.isFactoryBean = true;
}
return beanInstance;
}
}
其後便是呼叫FactoryBean實現類的getObject方法,完成工廠類的自定義功能增強
FactoryBean實現示例:
@Component
public class FactoryBeanTest implements FactoryBean {
@Override
public Object getObject() throws Exception {
//一些自定義功能
......
return new CustomTask();
}
@Override
public Class<?> getObjectType() {
return CustomTask.class;
}
}
springboot中呼叫例子:
@RestController
public class TestController {
@Autowired
private AnnotationConfigServletWebServerApplicationContext context;
@RequestMapping("/test")
public String test() throws Exception {
Object factoryBeanTest = context.getBean("factoryBeanTest");
System.out.println(factoryBeanTest.toString());
FactoryBean bean = (FactoryBean)context.getBean("&factoryBeanTest");
CustomTask customTask = (CustomTask)bean.getObject();
customTask.execute();
return bean.getObject().toString();
}
}