使用CGLIB来生成Bean对象
需要看一下SimpleInstantiationStrategy
类;
它是 Spring 用来生成Bean对象的默认类;
它提供了两种实例化Bean对象的方法
- BeanUtils,使用Java原生的反射功能
- CGLIB
public class SimpleInstantiationStrategy implements InstantiationStrategy { @Override public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) { // Don't override the class with CGLIB if no overrides. if (bd.getMethodOverrides().isEmpty()) { //这里取得指定的构造器或者生成对象的工厂方法来对Bean进行实例化 Constructor<?> constructorToUse; synchronized (bd.constructorArgumentLock) { constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod; if (constructorToUse == null) { final Class<?> clazz = bd.getBeanClass(); if (clazz.isInterface()) { throw new BeanInstantiationException(clazz, "Specified class is an interface"); } try { if (System.getSecurityManager() != null) { constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() { @Override public Constructor<?> run() throws Exception { return clazz.getDeclaredConstructor((Class[]) null); } }); } else { constructorToUse = clazz.getDeclaredConstructor((Class[]) null); } bd.resolvedConstructorOrFactoryMethod = constructorToUse; } catch (Throwable ex) { throw new BeanInstantiationException(clazz, "No default constructor found", ex); } } } //通过BeanUtils进行实例化,这个BeanUtils的实例化通过Constructor来实例化Bean,在BeanUtils中可以看到具体的调用ctor.newInstance(args) return BeanUtils.instantiateClass(constructorToUse); } else { // 使用CGLIB来实例化对象 return instantiateWithMethodInjection(bd, beanName, owner); } } }
4 Bean之间依赖关系的处理
依赖关系处理的入口是前面提到的populateBean
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { // 尝试从BeanDefinition中获取PropertyValue的属性集合,还没有值 PropertyValues pvs = mbd.getPropertyValues(); // 设置上面的PropertyValues的值,默认是getResolvedAutowiredMode方法返回0 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } if (hasInstAwareBpps) { // Autowired for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; pvs = ibp.postProcessPropertyValues(//瞅到没,这个方法哦~~~ pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } if (needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); } } applyPropertyValues(beanName, mbd, bw, pvs); }
由其涉及面广,仅简要介绍依赖关系处理的流程:
在populateBean方法中
首先取得在BeanDefinition中设置的property值,然后开始依赖注入的过程
首先处理Autowire的注入,可以by Name/Type,之后对属性进行注入
接着需要对Bean Reference进行解析
在对ManageList、ManageSet、ManageMap等进行解析完之后,就已经为依赖注入准备好了条件;
这是真正把Bean对象设置到它所依赖的另一个Bean属性中去的地方.
依赖注入发生在BeanWrapper的setPropertyValues中
具体的完成却是在BeanWrapper的子类BeanWrapperImpl中实现;
它会完成Bean的属性值的注入,其中包括对Array的注入、对List等集合类以及对非集合类的域进行注入
经过一系列的注入,这样就完成了对各种Bean属性的依赖注入过程
在Bean的创建和对象依赖注入的过程中,需要依据BeanDefinition中的信息来递归地完成依赖注入
从前面的几个递归过程中可以看到,这些递归都是以getBean为入口
一个递归是在上下文中查找需要的Bean和创建Bean的递归调用
另一个递归是在依赖注入时,通过递归调用容器的getBean方法,得到当前Bean的依赖Bean,同时也触发对依赖Bean的创建和注入。
在对Bean的属性进行依赖注入时,解析也是一个递归的过程
根据依赖关系,层层完成Bean的创建和注入,直到最后完成当前Bean的创建
有了这个顶层Bean的创建和对它属性依赖注入的完成,意味着和当前Bean相关的整个依赖链的注入也就完成了
在Bean创建和依赖注入完成后,在容器中建立起一系列依靠依赖关系联系起来的Bean,这个Bean已经不再是简单的Java对象了;
该Bean系列以及Bean之间的依赖关系建立完成之后,通过IoC的相关接口方法,就可以非常方便地供上层应用使用了。
5 lazy-init属性和预实例化
在前面的refresh
中,可看到调用了finishBeanFactoryInitialization
来对配置了lazy-init
的Bean进行处理
其实在这个方法中,封装了对lazy-init属性的处理,实际的处理是在DefaultListableBeanFactory这个基本容器的preInstantiateSingleton方法中完成的
该方法对单例Bean完成预实例化,这个预实例化的完成巧妙地委托给了容器来实现
如果需要预实例化,那么就直接在这里采用getBean去触发依赖注入