spring技术内幕笔记:ApplicationContext和Bean的初始化及销毁

来源:互联网 发布:adobe encoder mac 编辑:程序博客网 时间:2024/06/05 04:37

spring版本:4.3.8.RELEASE

ApplicationContex容器自身也有一个初始化和销t毁关闭的过程。ApplicationContext启动的过程是在AbstractApplicationContext中实现的。在使用应用上下文时需要做一些准备工作,这些准备工作在prepareBeanFactory方法中实现,在这个方法中,为容器配置了ClassLoader、PropertyEditor和BeanPostProcesser等,为容器的启动做好了必要的准备工作。

public abstract class AbstractApplicationContext extends DefaultResourceLoaderimplements ConfigurableApplicationContext, DisposableBean {    /** * Configure the factory's standard context characteristics, * such as the context's ClassLoader and post-processors. * @param beanFactory the BeanFactory to configure */protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// Tell the internal bean factory to use the context's class loader etc.beanFactory.setBeanClassLoader(getClassLoader());beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));// Configure the bean factory with context callbacks.beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));beanFactory.ignoreDependencyInterface(EnvironmentAware.class);beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);beanFactory.ignoreDependencyInterface(MessageSourceAware.class);beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);// BeanFactory interface not registered as resolvable type in a plain factory.// MessageSource registered (and found for autowiring) as a bean.beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class, this);beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);beanFactory.registerResolvableDependency(ApplicationContext.class, this);// Register early post-processor for detecting inner beans as ApplicationListeners.beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));// Detect a LoadTimeWeaver and prepare for weaving, if found.if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));// Set a temporary ClassLoader for type matching.beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}// Register default environment beans.if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());}if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());}if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());}}/** * 容器关闭完成的一系列工作 */protected void doClose() {if (this.active.get() && this.closed.compareAndSet(false, true)) {if (logger.isInfoEnabled()) {logger.info("Closing " + this);}LiveBeansView.unregisterApplicationContext(this);try {// Publish shutdown event.publishEvent(new ContextClosedEvent(this));}catch (Throwable ex) {logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);}// Stop all Lifecycle beans, to avoid delays during individual destruction.try {getLifecycleProcessor().onClose();}catch (Throwable ex) {logger.warn("Exception thrown from LifecycleProcessor on context close", ex);}// Destroy all cached singletons in the context's BeanFactory.destroyBeans();// Close the state of this context itself.closeBeanFactory();// Let subclasses do some final clean-up if they wish...onClose();this.active.set(false);}}}
2.Spring IoC容器在对Bean的生命周期进行管理时提供了Bean生命周期各个时间点的回调。
Bean生命周期:
(1)创建Bean实例
(2)为Bean实例设置属性
(3)调用Bean的初始化方法
(4)应用通过IoC容器使用Bean
(5)当容器关闭时,调用Bean的销毁方法
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactoryimplements AutowireCapableBeanFactory {/** * 初始化给定的Bean实例, 采用工厂的回调函数、初始化方法和bean的后置处理器 */protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged(new PrivilegedAction<Object>() {@Overridepublic Object run() {invokeAwareMethods(beanName, bean);return null;}}, getAccessControlContext());}else {//调用一系列的aware接口实现invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {//调用invokeInitMethods方法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;}//---------------------------------------------------------------------      // 调用Bean的初始化方法之前,会调用一系列的aware接口实现,把相关的BeanName、BeanClassLoader以及    // BeanFactory注入到Bean中。接着会看到对invokeInitMethods的调用,还有启动afterPropertiesSet的过程,    // 这需要Bean实现InitializingBean的接口,对应的初始化处理可以在InitiallizingBean的接口afterPropertiesSet方法中实现。    //---------------------------------------------------------------------  private void invokeAwareMethods(final String beanName, final Object bean) {if (bean instanceof Aware) {if (bean instanceof BeanNameAware) {((BeanNameAware) bean).setBeanName(beanName);}if (bean instanceof BeanClassLoaderAware) {((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());}if (bean instanceof BeanFactoryAware) {((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}}/** * Give a bean a chance to react now all its properties are set, * and a chance to know about its owning bean factory (this object). * This means checking whether the bean implements InitializingBean or defines * a custom init method, and invoking the necessary callback(s) if it does. * @param beanName the bean name in the factory (for debugging purposes) * @param bean the new bean instance we may need to initialize * @param mbd the merged bean definition that the bean was created with * (can also be {@code null}, if given an existing bean instance) * @throws Throwable if thrown by init methods or by the invocation process * @see #invokeCustomInitMethod */protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)throws Throwable {boolean isInitializingBean = (bean instanceof InitializingBean);if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {if (logger.isDebugEnabled()) {logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");}if (System.getSecurityManager() != null) {try {AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {@Overridepublic Object run() throws Exception {((InitializingBean) bean).afterPropertiesSet();return null;}}, getAccessControlContext());}catch (PrivilegedActionException pae) {throw pae.getException();}}else {//启动afterPropertiesSet的过程,需要Bean实现InitializingBean的接口((InitializingBean) bean).afterPropertiesSet();}}if (mbd != null) {String initMethodName = mbd.getInitMethodName();if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&!mbd.isExternallyManagedInitMethod(initMethodName)) {invokeCustomInitMethod(beanName, bean, mbd);}}}//---------------------------------------------------------------------      // 最后,会看到判断Bean是否配置有initMethod,如果有通过invokeCustionInitMethod方法来直接调用,完成Bean的初始化。    // 在对initMethod的调用中,可以看到首先需要得到Bean定义的initMethod,然后通过JDK的反射机制得到Method对象,直接调用在Bean定义中声明的初始化方法。    //---------------------------------------------------------------------  /** * Invoke the specified custom init method on the given bean. * Called by invokeInitMethods. * <p>Can be overridden in subclasses for custom resolution of init * methods with arguments. * @see #invokeInitMethods */protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {String initMethodName = mbd.getInitMethodName();final Method initMethod = (mbd.isNonPublicAccessAllowed() ?BeanUtils.findMethod(bean.getClass(), initMethodName) :ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));if (initMethod == null) {if (mbd.isEnforceInitMethod()) {throw new BeanDefinitionValidationException("Couldn't find an init method named '" +initMethodName + "' on bean with name '" + beanName + "'");}else {if (logger.isDebugEnabled()) {logger.debug("No default init method named '" + initMethodName +"' found on bean with name '" + beanName + "'");}// Ignore non-existent default lifecycle methods.return;}}if (logger.isDebugEnabled()) {logger.debug("Invoking init method  '" + initMethodName + "' on bean with name '" + beanName + "'");}if (System.getSecurityManager() != null) {AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {@Overridepublic Object run() throws Exception {ReflectionUtils.makeAccessible(initMethod);return null;}});try {AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {@Overridepublic Object run() throws Exception {initMethod.invoke(bean);return null;}}, getAccessControlContext());}catch (PrivilegedActionException pae) {InvocationTargetException ex = (InvocationTargetException) pae.getException();throw ex.getTargetException();}}else {try {ReflectionUtils.makeAccessible(initMethod);initMethod.invoke(bean);}catch (InvocationTargetException ex) {throw ex.getTargetException();}}}@Overridepublic void destroyBean(Object existingBean) {//销毁beannew DisposableBeanAdapter(existingBean, getBeanPostProcessors(), getAccessControlContext()).destroy();}}

3.销毁方法在DisposableBeanAdapter中有实现。

@SuppressWarnings("serial")class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {    @Overridepublic void destroy() {if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {processor.postProcessBeforeDestruction(this.bean, this.beanName);}}if (this.invokeDisposableBean) {if (logger.isDebugEnabled()) {logger.debug("Invoking destroy() on bean with name '" + this.beanName + "'");}try {if (System.getSecurityManager() != null) {AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {@Overridepublic Object run() throws Exception {((DisposableBean) bean).destroy();return null;}}, acc);}else {((DisposableBean) bean).destroy();}}catch (Throwable ex) {String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";if (logger.isDebugEnabled()) {logger.warn(msg, ex);}else {logger.warn(msg + ": " + ex);}}}if (this.destroyMethod != null) {invokeCustomDestroyMethod(this.destroyMethod);}else if (this.destroyMethodName != null) {Method methodToCall = determineDestroyMethod();if (methodToCall != null) {invokeCustomDestroyMethod(methodToCall);}}}}


原创粉丝点击