Spring源码解析笔记7——bean的初始化

在bean的配置时,bean中有一个init-method的属性,这个属性的作用是在bean实例化前调用init-method指定的方法来根据用户业务进行相应的实例化。这一步主要是通过this.initializeBean(beanName, existingBean, bd)方法来实现。

//源码如下:
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
        if(System.getSecurityManager() != null) {
            AccessController.doPrivileged(new PrivilegedAction() {
                public Object run() {
                    AbstractAutowireCapableBeanFactory.this.invokeAwareMethods(beanName, bean);
                    return null;
                }
            }, this.getAccessControlContext());
        } else {
            this.invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if(mbd == null || !mbd.isSynthetic()) {

            //应用后处理
            wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        }

        try {

            //激活用户自定义的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()) {

            //后处理的应用
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

在分析这段函数之前,先介绍一下Aware的使用。
1.定义普通bean。

public class Hello {
    public void say(){
        System.out.println("hello");
    }
}

2.定义BeanFactoryAware类型的bean。

public class Test implements BeanFactoryAware{

    private BeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    public void testAware(){
        Hello hello = (Hello) beanFactory.getBean("hello");
        hello.say();
    }
}

3.测试,结果会在控制台打印出来“hello”。

public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("test.xml");
        Test test = (Test) ctx.getBean("test");
        test.testAware();
    }
  • 查看spring的实现方式,是通过invokeAwareMethods来实现的。
//invokeAwareMethods源码。
private void invokeAwareMethods(String beanName, Object bean) {
        if(bean instanceof Aware) {
            if(bean instanceof BeanNameAware) {
                ((BeanNameAware)bean).setBeanName(beanName);
            }

            if(bean instanceof BeanClassLoaderAware) {
                ((BeanClassLoaderAware)bean).setBeanClassLoader(this.getBeanClassLoader());
            }

            if(bean instanceof BeanFactoryAware) {
                ((BeanFactoryAware)bean).setBeanFactory(this);
            }
        }

    }
  • 继续查看applyBeanPostProcessorsBeforeInitialization,在调用用户自定义初始化前会调用此方法。
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;
        Iterator var4 = this.getBeanPostProcessors().iterator();

        do {
            if(!var4.hasNext()) {
                return result;
            }

            BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
            result = beanProcessor.postProcessBeforeInitialization(result, beanName);
        } while(result != null);

        return result;
    }
  • 继续查看applyBeanPostProcessorsAfterInitialization,在调用用户自定义初始化后会调用此方法。
 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;
        Iterator var4 = this.getBeanPostProcessors().iterator();

        do {
            if(!var4.hasNext()) {
                return result;
            }

            BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
            result = beanProcessor.postProcessAfterInitialization(result, beanName);
        } while(result != null);

        return result;
    }
  • 调用用户自定义的初始化方法是通过this.invokeInitMethods(beanName, wrappedBean, mbd);去调用的。
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {

        //首先会检查是否是InitializingBean,如果是的话需要调用afterPropertiesSet方法。
        boolean isInitializingBean = bean instanceof InitializingBean;
        if(isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
            if(this.logger.isDebugEnabled()) {
                this.logger.debug("Invoking afterPropertiesSet() on bean with name \'" + beanName + "\'");
            }

            if(System.getSecurityManager() != null) {
                try {
                    AccessController.doPrivileged(new PrivilegedExceptionAction() {
                        public Object run() throws Exception {
                            ((InitializingBean)bean).afterPropertiesSet();
                            return null;
                        }
                    }, this.getAccessControlContext());
                } catch (PrivilegedActionException var6) {
                    throw var6.getException();
                }
            } else {

                //属性初始化后的处理。
                ((InitializingBean)bean).afterPropertiesSet();
            }
        }

        if(mbd != null) {
            String initMethodName = mbd.getInitMethodName();
            if(initMethodName != null && (!isInitializingBean || !"afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) {

                //调用自定义初始化方法。
                this.invokeCustomInitMethod(beanName, bean, mbd);
            }
        }

    }
  • this.registerDisposableBeanIfNecessary(beanName, bean, mbd),此方法是spring提供了销毁方法的扩展入口,通过配置属性destroy-method来实现,除此之外,用户还可以通过处理器DestructionAwareBeanPostProcessers来统一处理bean的销毁方法。
//源码如下:
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
        AccessControlContext acc = System.getSecurityManager() != null?this.getAccessControlContext():null;
        if(!mbd.isPrototype() && this.requiresDestruction(bean, mbd)) {
            if(mbd.isSingleton()) {

                /**
                    单例模式下注册需要销毁的bean,此方法中会处理实现DisposableBean的bean。
                    并且对所有的bean使用DestructionAwareBeanPostProcessers处理。
                **/
                this.registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, this.getBeanPostProcessors(), acc));
            } else {

                //自定义scope的处理。
                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, this.getBeanPostProcessors(), acc));
            }
        }

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值