Java实例化一定在初始化后面吗

对于类的初始化和实例化。实例化会不会一定是在初始化的基础上呢?之前验证以为实例化之前肯定会初始化,但是好像理解有问题,比如说springioc的bean的生命周期是4阶段,第一阶段是实例化,第三阶段是初始化,这样子不就是说明了初始化也可以在实例化后面了吗?也许之前理解有问题,看看有哪些uu浇浇

  • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/644925
  • 你也可以参考下这篇文章:spring 使用@Bean修饰的方法,直接调用方法设置对象和用形参注入设置对象一样吗
  • 除此之外, 这篇博客: 还记不住Spring Bean的生命周期?看这篇你就知道方法了!中的 四、销毁阶段 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 在容器关闭的时候,会进入Bean的销毁阶段,代码从AbstractApplicationContext的close()方法开始

    不急着进入close()方法,先看一下第一节代码中最末尾的方法:

    	protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
    		AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
            //如果Bean不是多例且需要在容器关闭时销毁
    		if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
    			if (mbd.isSingleton()) {
                    //给当前Bean绑定一个DisposableBeanAdapter
    				registerDisposableBean(beanName,
    						new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
    			}
    			else {
    				// A bean with a custom scope...
    				Scope scope = this.scopes.get(mbd.getScope());
    				if (scope == null) {
    					throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
    				}
    				scope.registerDestructionCallback(beanName,
    						new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
    			}
    		}
    	}
    
    	public void registerDisposableBean(String beanName, DisposableBean bean) {
    		synchronized (this.disposableBeans) {
    			this.disposableBeans.put(beanName, bean);
    		}
    	}

    在registerDisposableBeanIfNecessary中,会对每一个需要在容器关闭时进行销毁的单例Bean,绑定对应的DisposableBeanAdapter对象。最后把这些Bean及其DisposableBeanAdapter放入进名称为disposableBeans的map中,以供后续使用。

    现在我们进入AbstractApplicationContext的close()方法

    一路上兜兜转转,会进入到DefaultSingletonBeanRegistry的destroySingletons方法中

    	public void destroySingletons() {
    		String[] disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
    		
    		for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
    			destroySingleton(disposableBeanNames[i]);
    		}
            //省略部分代码
    	}

    先拿到所有待销毁Bean的名称,挨个调用destroySingleton方法,一直往下走,最终会进入到DefaultSingletonBeanRegistry的destroyBean中

    其中核心的一句

    		// Actually destroy the bean now...
    		bean.destroy();
    		

    按照beanName从disposableBeans中获取到bean对应的DisposableBeanAdapter,调用其destroy方法

        public void destroy() {
            //调用被@PreDestroy注解修饰的方法
            //具体可以跟进InitDestroyAnnotationBeanPostProcessor类
            if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
                for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
                    processor.postProcessBeforeDestruction(this.bean, this.beanName);
                }
            }
    
            //如果实现了DisposableBean接口,则调用destroy方法
            if (this.invokeDisposableBean) {
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                        ((DisposableBean) this.bean).destroy();
                        return null;
                    }, this.acc);
                } else {
                    ((DisposableBean) this.bean).destroy();
                }
            }
            
            //调用xml中自定义的destroy-method方法
            if (this.destroyMethod != null) {
                invokeCustomDestroyMethod(this.destroyMethod);
            } else if (this.destroyMethodName != null) {
                Method methodToCall = determineDestroyMethod(this.destroyMethodName);
                if (methodToCall != null) {
                    invokeCustomDestroyMethod(methodToCall);
                }
            }
        }

    到这里,Bean的销毁过程基本就结束了,我们使用一张图来概括下:

     


  • 您还可以看一下 唐世林老师的Java面试题精选集锦课程中的 8、【Spring面试题】什么是bean的自动装配,有哪些装配方式小节, 巩固相关知识点

当一个类被加载时,会先进行类的实例化,然后才会进行初始化。Spring IOC中,实例化和初始化的顺序也是一样的,先实例化Bean对象,然后再进行初始化。初始化为基本类型的成员变量赋默认值,为引用类型的成员变量赋null值等。