@Override public Object getBean(String name) throws BeansException { String beanName = BeanFactoryUtils.transformedBeanName(name); Object bean = this.beans.get(beanName); if (bean == null) { throw new NoSuchBeanDefinitionException(beanName, "Defined beans are [" + StringUtils.collectionToCommaDelimitedString(this.beans.keySet()) + "]"); } // Don't let calling code try to dereference the // bean factory if the bean isn't a factory if (BeanFactoryUtils.isFactoryDereference(name) && !(bean instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(beanName, bean.getClass()); } if (bean instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) { try { return ((FactoryBean<?>) bean).getObject(); } catch (Exception ex) { throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex); } } else { return bean; } }
/** * Get the object for the given bean instance, either the bean * instance itself or its created object in case of a FactoryBean. * @param beanInstance the shared bean instance * @param name name that may include factory dereference prefix * @param beanName the canonical bean name * @param mbd the merged bean definition * @return the object to expose for the bean */ protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, RootBeanDefinition mbd) { // Don't let calling code try to dereference the factory if the bean isn't a factory. if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass()); } // Now we have the bean instance, which may be a normal bean or a FactoryBean. // If it's a FactoryBean, we use it to create a bean instance, unless the // caller actually wants a reference to the factory. if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance; } Object object = null; if (mbd == null) { 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; }
private Optional<Object> tryToGetBean(ApplicationContext applicationContext, String beanName) { try { //null is possible when mocking factoryBean without default return value return Optional.ofNullable(applicationContext.getBean(beanName)); } catch (NoSuchBeanDefinitionException | BeanIsNotAFactoryException ex) { return Optional.empty(); } }
public Object getBean(String name) throws BeansException { String beanName = BeanFactoryUtils.transformedBeanName(name); Object bean = this.beans.get(beanName); if (bean == null) { throw new NoSuchBeanDefinitionException(beanName, "Defined beans are [" + StringUtils.collectionToCommaDelimitedString(this.beans.keySet()) + "]"); } // Don't let calling code try to dereference the // bean factory if the bean isn't a factory if (BeanFactoryUtils.isFactoryDereference(name) && !(bean instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(beanName, bean.getClass()); } if (bean instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) { try { return ((FactoryBean<?>) bean).getObject(); } catch (Exception ex) { throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex); } } else { return bean; } }
/** * It should be illegal to dereference a normal bean * as a factory */ public void testRejectsFactoryGetOnNormalBean() { try { getBeanFactory().getBean("&rod"); fail("Shouldn't permit factory get on normal bean"); } catch (BeanIsNotAFactoryException ex) { // Ok } }
/** * It should be illegal to dereference a normal bean as a factory. */ @Test(expected = BeanIsNotAFactoryException.class) public void rejectsFactoryGetOnNormalBean() { getBeanFactory().getBean("&rod"); }