Spring创建bean之初始化Bean和注册DisposableBean

初始化Bean
bean配置的时候,有一个init-method的属性,这个属性就是在bean初始化的时候调用指定的方法来进行初始化.

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
		// 判断是否需要权限
        if (System.getSecurityManager() != null) {
        	// 需要权限
            AccessController.doPrivileged(() -> {
                this.invokeAwareMethods(beanName, bean);
                return null;
            }, this.getAccessControlContext());
        } else {
        	// 不需要权限直接调用
        	// 1、对特殊的bean处理:Aware、BeanClassLoaderAware、BeanFactoryAware
            this.invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
        	// 2、应用后处理器
            wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        }

        try {
        	// 3、激活用户自定义的init方法
            this.invokeInitMethods(beanName, wrappedBean, mbd);
        } catch (Throwable var6) {
            throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
        }

        if (mbd == null || !mbd.isSynthetic()) {
        	// 4、后处理器应用
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

1、激活Aware方法
Spring中提供了一些Aware相关接口,比如:BeanFactoryAware、ApplicationContextAware等,实现这些Aware接口的bean在被初始化后,会得到对应的资源,比如实现BeanFactoryAware的bean在初始化后,Spring容器将会注入BeanFactory的实例,实现ApplicationContextAware的bean,在bean被初始化后,将会被出入ApplicationContext的实例.

2、处理器应用
BeanPostProcessor是Spring中开放式架构中的一个亮点,给用户去扩展或者更改Spring,除了BeanPostProcessor还有很多其他的PostProcessor,大部分是以此为基础,继承BeanPostProcessor.
在调用客户自定义的初始化方法前及调用自定义初始化方法后会分别调用BeanPostProcessor的postProcessorBeforeInitialization和postProcessorAfterInitialization方法.

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;

        Object current;
        for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
            BeanPostProcessor processor = (BeanPostProcessor)var4.next();
            current = processor.postProcessBeforeInitialization(result, beanName);
            if (current == null) {
                return result;
            }
        }

        return result;
    }
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;

        Object current;
        for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
            BeanPostProcessor processor = (BeanPostProcessor)var4.next();
            current = processor.postProcessAfterInitialization(result, beanName);
            if (current == null) {
                return result;
            }
        }

        return result;
    }

3、激活自定义的init方法
其实除了使用配置init-method外,还有使用自定的bean实现InitializingBean接口,并在afterPropertiesSet中实现自己的初始化业务逻辑.
指定顺序是先执行afterPropertiesSet先执行,而init-method后执行.

    protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) throws Throwable {
        boolean isInitializingBean = bean instanceof InitializingBean;
        if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
            }

            if (System.getSecurityManager() != null) {
                try {
                    AccessController.doPrivileged(() -> {
                        ((InitializingBean)bean).afterPropertiesSet();
                        return null;
                    }, this.getAccessControlContext());
                } catch (PrivilegedActionException var6) {
                    throw var6.getException();
                }
            } else {
            	// 1、先执行
                ((InitializingBean)bean).afterPropertiesSet();
            }
        }

        if (mbd != null && bean.getClass() != NullBean.class) {
            String initMethodName = mbd.getInitMethodName();
            if (StringUtils.hasLength(initMethodName) && (!isInitializingBean || !"afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) {
            	// 2、再执行init-method方法
                this.invokeCustomInitMethod(beanName, bean, mbd);
            }
        }

    }

注册DisposableBean
同样的,Spring也提供了销毁方法的扩展入口,既可以通过destroy-method方法,也可以通过注册后处理器DestructionAwareBeanPostProcessor来统一处理bean的销毁方法.

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
		AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
		if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
			if (mbd.isSingleton()) {
				// 代理模式下注册需要销毁的bean,此方法中会处理实现DisposableBean的bean
				// 并对所有的bean使用DestructionAwareBeanPostProcessors处理
				// DisposableBean DestructionAwareBeanPostProcessors
				registerDisposableBean(beanName,
						new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
			}
			else {
				// 自定义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));
			}
		}
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值