getObjectForBeanInstance
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. //如果bean名称是以&开头的,默认是FactoryBean对象 if (BeanFactoryUtils.isFactoryDereference(name)) { if (beanInstance instanceof NullBean) { return beanInstance; } if (!(beanInstance instanceof FactoryBean)) { //&开头的如果不是NullBean throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass()); } if (mbd != null) { // mbd.isFactoryBean = true; } return beanInstance; } // 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. //bean名称不是&开头的,并且不是FactoryBean类型的直接返回bean实例 if (!(beanInstance instanceof FactoryBean)) { return beanInstance; } Object object = null; if (mbd != null) { mbd.isFactoryBean = true; } else { //从缓存中,获取FactoryBean实例化的bean 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()); //通过FactoryBean来实例化bean object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; }
如果bean名称是以&开头的,默认是FactoryBean对象 ,不是的话直接抛异常
/** * Used to dereference a {@link FactoryBean} instance and distinguish it from * beans <i>created</i> by the FactoryBean. For example, if the bean named * {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject} * will return the factory, not the instance returned by the factory. */ String FACTORY_BEAN_PREFIX = "&";
public static boolean isFactoryDereference(@Nullable String name) { return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)); }
getObjectFromFactoryBean
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { if (factory.isSingleton() && containsSingleton(beanName)) { synchronized (getSingletonMutex()) { // 从缓存中获取 Object object = this.factoryBeanObjectCache.get(beanName); if (object == null) { object = doGetObjectFromFactoryBean(factory, beanName); // Only post-process and store if not put there already during getObject() call above // (e.g. because of circular reference processing triggered by custom getBean calls) Object alreadyThere = this.factoryBeanObjectCache.get(beanName); if (alreadyThere != null) { object = alreadyThere; } else { if (shouldPostProcess) { if (isSingletonCurrentlyInCreation(beanName)) { // Temporarily return non-post-processed object, not storing it yet.. return object; } //将BeanName放入正在创建的Bean的Set集合 beforeSingletonCreation(beanName); try { // 对FactoryBean创建的对象进行后置处理 object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's singleton object failed", ex); } finally { afterSingletonCreation(beanName); } } if (containsSingleton(beanName)) { this.factoryBeanObjectCache.put(beanName, object); } } } return object; } } else { Object object = doGetObjectFromFactoryBean(factory, beanName); if (shouldPostProcess) { try { object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex); } } return object; } }
doGetObjectFromFactoryBean最终调用FactorBean的getObject()方法,走自定义逻辑创建Bean
将BeanName放入正在创建的Bean的Set集合
protected void beforeSingletonCreation(String beanName) { if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } }
将BeanName从正在创建的Bean的Set集合中移除
/** * Callback after singleton creation. * <p>The default implementation marks the singleton as not in creation anymore. * @param beanName the name of the singleton that has been created * @see #isSingletonCurrentlyInCreation */ protected void afterSingletonCreation(String beanName) { if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) { throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation"); } }
FactoryBean
spring提供的一个扩展机制,可以自定义对象的创建过程
public interface FactoryBean<T> { String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType"; @Nullable T getObject() throws Exception; @Nullable Class<?> getObjectType(); default boolean isSingleton() { return true; } }
public class Student { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
@Component("studentFactoryBean") public class StudentFactoryBean implements FactoryBean<Student> { @Override public Student getObject() throws Exception { System.out.println("StudentFactoryBean create student"); Student student = new Student(); student.setName("jack"); student.setAge(18); return student; } @Override public Class<?> getObjectType() { return Student.class; } }
public static void main(String[] args) { ApplicationContext ctx = new AnnotationConfigApplicationContext("cn.dotfashion.soa.demo.**"); Student student = (Student) ctx.getBean("studentFactoryBean"); FactoryBean student1 = (FactoryBean) ctx.getBean("&studentFactoryBean"); System.out.println(student); System.out.println(student1); }
输出
仅通过名称
studentFactoryBean
获取单的是FactoryBean创建的对象,通过
&studentFactoryBean
获取了Student对象创建工厂BeanStudentFactoryBean create student cn.dotfashion.soa.demo.factoyBean.Student@5f683daf[name=jack,age=18] cn.dotfashion.soa.demo.factoyBean.StudentFactoryBean@7e9131d5