在牛客面经上遇到的一个面试题。忽然想尝试下
而后就开始做了

测试

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");        TestDao testDao = applicationContext.getBean(TestDao.class);        ((ClassPathXmlApplicationContext) applicationContext).close();

测试的bean

@Componentpublic class TestDao  implements InitializingBean, DisposableBean {    public TestDao() {        System.out.println("constructor");    }    @Async    public void query(){        System.out.println("Hello Spring!");    }    @Override    public void afterPropertiesSet() throws Exception {        System.out.println("afterPropertiesSet");    }    @PostConstruct    public void PostConstruct(){        System.out.println("PostConstruct");    }    public void InitMethod(){        System.out.println("InitMethod");    }    @Override    public void destroy() throws Exception {        System.out.println("destroy");    }    @PreDestroy    public void PreDestroy(){        System.out.println("PreDestroy");    }    public void destroyMethod(){        System.out.println("destroyMethod");    }}

xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:tx="http://www.springframework.org/schema/tx"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:context="http://www.springframework.org/schema/context"       xsi:schemaLocation="http://www.springframework.org/schema/beans        https://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/tx        https://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">    <context:annotation-config/>    <bean id="testDao" class="com.test.dao.TestDao" init-method="InitMethod" destroy-method="destroyMethod"></bean></beans>

执行之后打印的后果

总的来说就是打印的后果是构造方法->注解@PostConstruct办法->InitializingBean接口的afterPropertiesSet办法->xml中配置的init-method办法
同理销毁也是一样注解@PreDestroy办法->DisposableBean接口的destroy办法->xml中配置的destroy-method办法

源码

通过断点调试发现几个初始化办法都定位到了AbstractAutowireCapableBeanFactory的initializeBean办法中

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 {            invokeAwareMethods(beanName, bean);        }        Object wrappedBean = bean;        if (mbd == null || !mbd.isSynthetic()) {        //此处执行的是@PostConstruct注解的办法 InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);        }        try {        //执行的是afterPropertiesSet和init-method办法            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()) {            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);        }        return wrappedBean;    }

前面执行的两个办法
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)

        throws Throwable {    boolean isInitializingBean = (bean instanceof InitializingBean);    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {        if (logger.isTraceEnabled()) {            logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");        }        if (System.getSecurityManager() != null) {            try {                AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {                    ((InitializingBean) bean).afterPropertiesSet();                    return null;                }, getAccessControlContext());            }            catch (PrivilegedActionException pae) {                throw pae.getException();            }        }        else {        //执行afterPropertiesSet办法            ((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)) {                //执行的是xml中自定义的init-method办法            invokeCustomInitMethod(beanName, bean, mbd);        }    }}
欢送搜寻关注自己与敌人共同开发的微信面经小程序【大厂面试助手】和公众号【微瞰技术】