spring IoC (三)FactoryBean

在Bean实例化过程中FactoryBean的处理过程

  AbstractBeanFactory.getBean--->doGetBean--->getObjectForBeanInstance--->

FactoryBeanRegistrySupport.getObjectFromFactoryBean--->doGetObjectFromFactoryBean

 1     protected Object getObjectForBeanInstance(
 2             Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
 3 
 4         // Don't let calling code try to dereference the factory if the bean isn't a factory.
 5         if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
 6             throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
 7         }
 8 
 9         // Now we have the bean instance, which may be a normal bean or a FactoryBean.
10         // If it's a FactoryBean, we use it to create a bean instance, unless the
11         // caller actually wants a reference to the factory.
12         if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
13             return beanInstance;
14         }
15 
16         Object object = null;
17         if (mbd == null) {
18             object = getCachedObjectForFactoryBean(beanName);
19         }
20         if (object == null) {
21             // Return bean instance from factory.
22             FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
23             // Caches object obtained from FactoryBean if it is a singleton.
24             if (mbd == null && containsBeanDefinition(beanName)) {
25                 mbd = getMergedLocalBeanDefinition(beanName);
26             }
27             boolean synthetic = (mbd != null && mbd.isSynthetic());
28             object = getObjectFromFactoryBean(factory, beanName, !synthetic);
29         }
30         return object;
31     }

FactoryBeanRegistrySupport.getObjectFromFactoryBean

 1     protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
 2         if (factory.isSingleton() && containsSingleton(beanName)) {
 3             synchronized (getSingletonMutex()) {
 4                 Object object = this.factoryBeanObjectCache.get(beanName);
 5                 if (object == null) {
 6                     object = doGetObjectFromFactoryBean(factory, beanName);
 7                     // Only post-process and store if not put there already during getObject() call above
 8                     // (e.g. because of circular reference processing triggered by custom getBean calls)
 9                     Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
10                     if (alreadyThere != null) {
11                         object = alreadyThere;
12                     }
13                     else {
14                         if (object != null && shouldPostProcess) {
15                             try {
16                                 object = postProcessObjectFromFactoryBean(object, beanName);
17                             }
18                             catch (Throwable ex) {
19                                 throw new BeanCreationException(beanName,
20                                         "Post-processing of FactoryBean's singleton object failed", ex);
21                             }
22                         }
23                         this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
24                     }
25                 }
26                 return (object != NULL_OBJECT ? object : null);
27             }
28         }
29         else {
30             Object object = doGetObjectFromFactoryBean(factory, beanName);
31             if (object != null && shouldPostProcess) {
32                 try {
33                     object = postProcessObjectFromFactoryBean(object, beanName);
34                 }
35                 catch (Throwable ex) {
36                     throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
37                 }
38             }
39             return object;
40         }
41     }

doGetObjectFromFactoryBean

 1     private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
 2             throws BeanCreationException {
 3 
 4         Object object;
 5         try {
 6             if (System.getSecurityManager() != null) {
 7                 AccessControlContext acc = getAccessControlContext();
 8                 try {
 9                     object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
10                         public Object run() throws Exception {
11                                 return factory.getObject();
12                             }
13                         }, acc);
14                 }
15                 catch (PrivilegedActionException pae) {
16                     throw pae.getException();
17                 }
18             }
19             else {
20                 object = factory.getObject();
21             }
22         }
23         catch (FactoryBeanNotInitializedException ex) {
24             throw new BeanCurrentlyInCreationException(beanName, ex.toString());
25         }
26         catch (Throwable ex) {
27             throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
28         }
29 
30         // Do not accept a null value for a FactoryBean that's not fully
31         // initialized yet: Many FactoryBeans just return null then.
32         if (object == null && isSingletonCurrentlyInCreation(beanName)) {
33             throw new BeanCurrentlyInCreationException(
34                     beanName, "FactoryBean which is currently in creation returned null from getObject");
35         }
36         return object;
37     }

猜你喜欢

转载自www.cnblogs.com/toUpdating/p/9728304.html