目录
1、理解IOC/DI/DL
1.1、IOC -(Inversion Of Control)
1.2、DL-(Dependency looking )
1.3、DI-(Dependency injection )
2、Spring容器启动流程
3、Spring容器启动源码分析
4、小结
功能代码实现的:IOC ,依赖注入和依赖查找。
@SpringBootApplication public class SpringBootMainApp { @Resource //DI 依赖注入 private Person person; public static void main(String[] args) { //IOC,所谓的控制反转,容器载入类,将Bean实例化,然后交给spring容器Map托管; ApplicationContext app = new AnnotationConfigApplicationContext(AutowiredPersonConfig.class); //DL 依赖查找,在容器中查找id=person的Bean实例对象; Person person = (Person) app.getBean("person"); // TODO HERE } }分析:容器启动载入类AnnotaionConfigApplicationContext完成Bean的装载和注册,@Resource里面就简单的实现了bean的依赖查找和注入。
没有IOC之前,我们要使用对象的时候就需要自己先创建一个对象,自己控制对象的生产,获取相应的资源,另外每次产生一个对象就会往JVM内存中写入一些数据,占用了内存,也增加垃圾回收的行能消耗;
但是有了IOC之后,管理和控制就发生了反转: 控制了什么?对象的new创建和生命周期,相关的依赖资源获取; 反转给谁?管理权反转给Spring,由Spring的 ioc容器来控制Bean生命周期; 这个简单的过程其实就是IOC的过程,实际上等价于执行了下面代码:
第一步:判断是否加了相关的注解信息: 先判断如果变量加了@Resource注解 if (field.isAnnotationPresent(Resource.class)) { //todo 进行属性赋值; }第二步:完成DL-依赖查找,从容器map中获取实例Bean Person:
Person person = singletonObjects.get("person");其实这也就是完成了person实例变量的依赖查找和注入过程。
开始创建非懒加载的单实例业务Bean:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this context. if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } // Stop using the temporary ClassLoader for type matching. beanFactory.setTempClassLoader(null); // Allow for caching all bean definition metadata, not expecting further changes. beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons. //实例化所有剩下的非懒加载单实例业务Bean beanFactory.preInstantiateSingletons(); }得到所有需要实例化的单实例Bean的全路径名,bean信息的定义 -用来生成这个bean的,然后挨个循环实例化:
@Override public void preInstantiateSingletons() throws BeansException { String FACTORY_BEAN_PREFIX = "&"; //得到所有的需要实例化的Bean的名字 List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans… //挨个循环获取或者创建这个beanName; for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { final FactoryBean<?> factory = (FactoryBean<?>) bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } } else {//获取或者创建这个bean getBean(beanName); } } }在创建一个bean之前,先到ioc容器map中去获取相关的bean,如果该bean已经创建,则直接获取返回,不再创建,如果容器map中没有,则进行创建。这也是单例的体现,只创建一次,每次获取的对象都是同一个,可以验证打印它的地址是相同的。
@Override //获取bean信息 public <T> T getBean(String name, Class<T> requiredType) throws BeansException { return doGetBean(name, requiredType, null, false); } 继续获取bean: protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; //将bean标记为已创建 if (!typeCheckOnly) { markBeanAsCreated(beanName); } // Eagerly check singleton cache for manually registered singletons. //通过bean的名字到我们的 IOC大map-其实就是一个缓存 中获取 bean; Object sharedInstance = getSingleton(beanName); //如果缓存中有这个bean,则直接返回; if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } } bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } //如果缓存中没有这个bean,则直接开始创建这个bean; else { if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); }从缓存容器map中获取bean单实例;
//private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); protected Object getSingleton(String beanName, boolean allowEarlyReference) { //直接在map中get Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { //同步获取; singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } //如果容器中有bean,则直接返回; return singletonObject; }如果容器中有这个单实例bean则直接返回创建的流程结束;如果缓存中还没有我们需要的实例Bean,这时候就会开始创建我们的Bean实例:
创建createBean实例的具体步骤: 第一步:通过反射创建对象,new Person(); 第二步:属性赋值;person.set("king") 第三步:执行Bean初始化方法,对于动态代理的对象Bean进行init前后拦截增强; 具体实现如下: @Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. //给个机会返回一个代理对象,这里什么都没做,因为aop的bean是普通的bean的创建过程; Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } // Make sure bean class is actually resolved at this point, and // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. Class<?> resolvedClass = resolveBeanClass(mbd, beanName); try { //开始创建 Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }创建bean,这里已经有内存地址了,也就是完成了对象的实例化:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { //这里bean先创建对象,已经有内存地址;相当于Person person = new Person(); instanceWrapper = createBeanInstance(beanName, mbd, args); }Spring是通过反射来创建对象,通过createBeanInstance()发现具体创建对象步骤如下:
@Override public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) { // Don't override the class with CGLIB if no overrides. if (!bd.hasMethodOverrides()) { Constructor<?> constructorToUse; synchronized (bd.constructorArgumentLock) { constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod; //反射获取构造函数 constructorToUse = clazz.getDeclaredConstructor(); } catch (Throwable ex) { throw new BeanInstantiationException(clazz, "No default constructor found", ex); } } } //第一步:反射创建实例完成 等价于Person person = new Person(); return BeanUtils.instantiateClass(constructorToUse); } Object exposedObject = bean; try { //第二步:属性的赋值和初始化,等价于 person.setName("king"); populateBean(beanName, mbd, instanceWrapper); //第三步:bean的初始化 exposedObject = initializeBean(beanName, exposedObject, mbd); }initializedBean主要是对bean完成一些初始化工作,比如在做动态代理的时候,这里就用到了,对当前的Bean初始化执行前和执行后做一些增强的处理工作,
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else {//对bean的初始化 invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { //对bean出世化的前置处理器 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { //对bean初始化的后置处理器 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }至此,一个业务bean的实例化就完成了,结束之后,将这个bean放入到我们的IOC容器map中去,供后期业务 DI/DL使用;