/** * 一个单例bean的依赖注入和查找 */ public class SingletonBeanInjectLock { public static void main(String[] args) { // 创建Ioc容器 DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); GenericBeanDefinition beanDefinition = new GenericBeanDefinition(); // 定义初始化类 beanDefinition.setBeanClass(Person.class); // 用构造函数的方式初始化类 ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues(); constructorArgumentValues.addGenericArgumentValue("张三"); constructorArgumentValues.addGenericArgumentValue("北京"); constructorArgumentValues.addGenericArgumentValue(14212123); beanDefinition.setConstructorArgumentValues(constructorArgumentValues); //将beanDefinition注册到容器中 beanFactory.registerBeanDefinition("person",beanDefinition); System.out.println(beanFactory.getBean("person")); } }
这里我们直接定义了一个实例,采用手动注册的方式将bean对象注入到ioc容器中。我们来看这段代码在源码中具体做了哪些事情。
第一步创建DefaultListableBeanFactory对象这个就不用说了,看下面的GenericBeanDefinition。之前我们说过beanDefinition是spring中bean对象的描述类,包含一些bean对象的配置信息。比如像作用域啊,bean对象的类、构造函数、init-method、工厂类之类的。
这里我们创建了一个GenericBeanDefinition,并且将他的类设置为Person,并且设置了它的构造函数的参数,用构造函数初始化Bean对象。然后通过registerBeanDefinition注册到容器中。
这里的注入具体干了什么事情呢?
@Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { // 根据beanName查看是否已经有该bean对象存在 BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName); if (existingDefinition != null) { // 将之前的beanDefinition覆盖掉 // (这里删除了部分代码,实际上容器有个allowBeanDefinitionOverriding信息 // 默认为true,如果不为true不会进行覆盖操作) this.beanDefinitionMap.put(beanName, beanDefinition); } else { // 这里是判断当前是否已经有bean被创建了,如果有的话,需要加锁来保障线程安全 if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { // 保存该beanDefinition this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; // 从手动注册的bean类表中删除 removeManualSingletonName(beanName); } } else { // Still in startup registration phase this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); removeManualSingletonName(beanName); } this.frozenBeanDefinitionNames = null; } // 如果当前已经有缓存的beanDefinition,则重置beanDefinition if (existingDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } else if (isConfigurationFrozen()) { // 清空allBeanNamesByType、singletonBeanNamesByType缓存信息 clearByTypeCache(); } }
这样就把bean对象存到了Ioc容器中。那么当我们调用getBean时做了什么呢?
protected <T> T doGetBean( String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { String beanName = transformedBeanName(name); Object bean; // 查看当前是否是单例Bean对象 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { // 从缓存中获取单例Bean对象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // 找到对应的BeanDefinition对象 BeanFactory parentBeanFactory = getParentBeanFactory(); // 类似双亲委派机制,先找父容器中是否有,优先从父容器中获取bean信息 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType != null) { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { // 这里可以有些疑问,什么是MergedBeanDefinition? // 实际上之前我们在DefaultListableBeanFactory注册成功之后, // 把对应的beanDefinition存到beanDefinitionMap中了。 // 但是在AbstractBeanFactory中有个mergedBeanDefinitions, // 我们最终取的BeanDefinition也是从mergedBeanDefinitions中取的, // 所以我们需要合并到mergedBeanDefinitions中。 // 这个地方做的事情就是如果当前这个BeanDefinition需要合并,就放到 // mergedBeanDefinitions中,再返回该对象。 RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. // 查找依赖,并将依赖实例化 String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } registerDependentBean(dep, beanName); try { getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // Create bean instance. // 创建bean实例 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { // 这个方法实际上是写在AbstractAutowireCapableBeanFactory类中的 // 待会再看 return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { // 跟上面的isPrototypeCurrentlyInCreation对应 beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { // 这个地方是给其他作用域用的 比如RequestScope、SessionScope String scopeName = mbd.getScope(); if (!StringUtils.hasLength(scopeName)) { throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'"); } Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, () -> { // 跟上面的isPrototypeCurrentlyInCreation对应 beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } return (T) bean; }
spring创建对象的类:
实际上最后是InstantiationStrategy决定用哪种策略去创建初始化bean对象。
一共是两种,上面的SimpleInstantiationStrategy直接就用的Java反射。CglibSubclassingInstantiationStrategy采用cglib生成类方式,实例化对象。