zoukankan      html  css  js  c++  java
  • ApplicationContext的初始化与销毁&Bean的生命周期&BeanPostProcessor的使用&Aware使用(四)

    1.ApplicationContext的初始化以及销毁

    对于BeanFactory也有一个初始化和销毁关闭的过程,比如编程式的容器如下:

    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainApp.class);

    构造方法如下:

        public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
            this();
            register(componentClasses);
            refresh();
        }

    refresh是IoC的开始,方法如下:

        @Override
        public void refresh() throws BeansException, IllegalStateException {
            synchronized (this.startupShutdownMonitor) {
                // Prepare this context for refreshing.
                prepareRefresh();
    
                // Tell the subclass to refresh the internal bean factory.
                ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
                // Prepare the bean factory for use in this context.
                prepareBeanFactory(beanFactory);
    
                try {
                    // Allows post-processing of the bean factory in context subclasses.
                    postProcessBeanFactory(beanFactory);
    
                    // Invoke factory processors registered as beans in the context.
                    invokeBeanFactoryPostProcessors(beanFactory);
    
                    // Register bean processors that intercept bean creation.
                    registerBeanPostProcessors(beanFactory);
    
                    // Initialize message source for this context.
                    initMessageSource();
    
                    // Initialize event multicaster for this context.
                    initApplicationEventMulticaster();
    
                    // Initialize other special beans in specific context subclasses.
                    onRefresh();
    
                    // Check for listener beans and register them.
                    registerListeners();
    
                    // Instantiate all remaining (non-lazy-init) singletons.
                    finishBeanFactoryInitialization(beanFactory);
    
                    // Last step: publish corresponding event.
                    finishRefresh();
                }
    
                catch (BeansException ex) {
                    if (logger.isWarnEnabled()) {
                        logger.warn("Exception encountered during context initialization - " +
                                "cancelling refresh attempt: " + ex);
                    }
    
                    // Destroy already created singletons to avoid dangling resources.
                    destroyBeans();
    
                    // Reset 'active' flag.
                    cancelRefresh(ex);
    
                    // Propagate exception to caller.
                    throw ex;
                }
    
                finally {
                    // Reset common introspection caches in Spring's core, since we
                    // might not ever need metadata for singleton beans anymore...
                    resetCommonCaches();
                }
            }
        }

    org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory 是为启动过程做了一些准备工作,为容器配置了Classloader、PropertyEditor、BeanPostProcessor、Environment环境等信息,从而为容器启动做了必要的准备工作。

        /**
         * 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());
            }
        }

    同时,容器在关闭时也会做一系列的操作。在doClose中,先发出容器关闭的信号、然后将Bean逐个关闭,最后关闭容器自身。org.springframework.context.support.AbstractApplicationContext#doClose:

        protected void doClose() {
            // Check whether an actual close attempt is necessary...
            if (this.active.get() && this.closed.compareAndSet(false, true)) {
                if (logger.isDebugEnabled()) {
                    logger.debug("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.
                if (this.lifecycleProcessor != null) {
                    try {
                        this.lifecycleProcessor.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();
    
                // Reset local application listeners to pre-refresh state.
                if (this.earlyApplicationListeners != null) {
                    this.applicationListeners.clear();
                    this.applicationListeners.addAll(this.earlyApplicationListeners);
                }
    
                // Switch to inactive.
                this.active.set(false);
            }
        }

    2.  Bean的生命周期

    容器的实现是通过IoC来管理Bean的生命周期来实现的。Spring IoC容器在对Bean的生命周期进行管理时提供了Bean生命周期的各个时间点的回调。IoC中Bean的生命周期如下:

    (1)Bean实例的创建

    (2)为Bean实例设置属性

    (3)调用Bean的初始化方法

    (4)应用可以通过IoC容器使用Bean

    (5)容器关闭时,调用Bean的销毁方法

    在上一节IoC依赖注入过程中研究了Bean实例的创建、设置属性、调用Bean的初始化。

    (1) 实例的创建实际就是反射或者CGlib代理生成对象

    (2) 设置属性实际就是依赖注入

    (3) Bean的初始化方法:  依赖注入完成之后调用初始化initializeBean方法

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean

    protected Object initializeBean(String beanName, 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()) {
                wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
            }
    
            try {
                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;
        }
    
        private void invokeAwareMethods(String beanName, Object bean) {
            if (bean instanceof Aware) {
                if (bean instanceof BeanNameAware) {
                    ((BeanNameAware) bean).setBeanName(beanName);
                }
                if (bean instanceof BeanClassLoaderAware) {
                    ClassLoader bcl = getBeanClassLoader();
                    if (bcl != null) {
                        ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
                    }
                }
                if (bean instanceof BeanFactoryAware) {
                    ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
                }
            }
        }
    
        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 (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 {
                    ((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)) {
                    invokeCustomInitMethod(beanName, bean, mbd);
                }
            }
        }

    -1》在调用初始化方法之前,会先调用invokeAwareMethods 一系列的ware接口实现,把相关的BeanName、BeanClassLoader以及BeanFactory注入到Bean中去。

    -2》接着调用applyBeanPostProcessorsBeforeInitialization 处理BeanPostProcessor的postProcessBeforeInitialization 初始化之前逻辑。需要注意 @PostConstruct 注解声明的方法也是在这个阶段被调用的,其对应的BeanPostProcessor 是CommonAnnotationBeanPostProcessor

        public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
                throws BeansException {
    
            Object result = existingBean;
            for (BeanPostProcessor processor : getBeanPostProcessors()) {
                Object current = processor.postProcessBeforeInitialization(result, beanName);
                if (current == null) {
                    return result;
                }
                result = current;
            }
            return result;
        }

    CommonAnnotationBeanPostProcessor 处理逻辑如下:

    org.springframework.context.annotation.CommonAnnotationBeanPostProcessor继承自父类的postProcessBeforeInitialization方法

        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            // 找到PostConstruct 声明的方法
            LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
            try {
                // 反射调用
                metadata.invokeInitMethods(bean, beanName);
            }
            catch (InvocationTargetException ex) {
                throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
            }
            catch (Throwable ex) {
                throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
            }
            return bean;
        }

    寻找注解声明的方法如下:

        private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
            if (this.lifecycleMetadataCache == null) {
                // Happens after deserialization, during destruction...
                return buildLifecycleMetadata(clazz);
            }
            // Quick check on the concurrent map first, with minimal locking.
            LifecycleMetadata metadata = this.lifecycleMetadataCache.get(clazz);
            if (metadata == null) {
                synchronized (this.lifecycleMetadataCache) {
                    metadata = this.lifecycleMetadataCache.get(clazz);
                    if (metadata == null) {
                        metadata = buildLifecycleMetadata(clazz);
                        this.lifecycleMetadataCache.put(clazz, metadata);
                    }
                    return metadata;
                }
            }
            return metadata;
        }
    
        private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
            List<LifecycleElement> initMethods = new ArrayList<>();
            List<LifecycleElement> destroyMethods = new ArrayList<>();
            Class<?> targetClass = clazz;
    
            do {
                final List<LifecycleElement> currInitMethods = new ArrayList<>();
                final List<LifecycleElement> currDestroyMethods = new ArrayList<>();
    
                ReflectionUtils.doWithLocalMethods(targetClass, method -> {
                    if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
                        LifecycleElement element = new LifecycleElement(method);
                        currInitMethods.add(element);
                        if (logger.isTraceEnabled()) {
                            logger.trace("Found init method on class [" + clazz.getName() + "]: " + method);
                        }
                    }
                    if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
                        currDestroyMethods.add(new LifecycleElement(method));
                        if (logger.isTraceEnabled()) {
                            logger.trace("Found destroy method on class [" + clazz.getName() + "]: " + method);
                        }
                    }
                });
    
                initMethods.addAll(0, currInitMethods);
                destroyMethods.addAll(currDestroyMethods);
                targetClass = targetClass.getSuperclass();
            }
            while (targetClass != null && targetClass != Object.class);
    
            return new LifecycleMetadata(clazz, initMethods, destroyMethods);
        }

    CommonAnnotationBeanPostProcessor 构造里定义了对应的注解:

        public CommonAnnotationBeanPostProcessor() {
            setOrder(Ordered.LOWEST_PRECEDENCE - 3);
            setInitAnnotationType(PostConstruct.class);
            setDestroyAnnotationType(PreDestroy.class);
            ignoreResourceType("javax.xml.ws.WebServiceContext");
        }

    -3》接着调用invokeInitMethods方法,会看到启动afterPropertiesSet 的过程,当然这需要Bean实现InitializingBean 接口,对应的初始化处理可以在InitializingBean 接口的afterPropertiesSet 方法实现,同样是对Bean的一个回调。

    最后还会判断是否有initMethod,如果有那么通过invokeCustomInitMethod 直接调用最终完成对Bean的初始化。

    protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd)
                throws Throwable {
    
            String initMethodName = mbd.getInitMethodName();
            Assert.state(initMethodName != null, "No init method set");
            Method initMethod = (mbd.isNonPublicAccessAllowed() ?
                    BeanUtils.findMethod(bean.getClass(), initMethodName) :
                    ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
    
            if (initMethod == null) {
                if (mbd.isEnforceInitMethod()) {
                    throw new BeanDefinitionValidationException("Could not find an init method named '" +
                            initMethodName + "' on bean with name '" + beanName + "'");
                }
                else {
                    if (logger.isTraceEnabled()) {
                        logger.trace("No default init method named '" + initMethodName +
                                "' found on bean with name '" + beanName + "'");
                    }
                    // Ignore non-existent default lifecycle methods.
                    return;
                }
            }
    
            if (logger.isTraceEnabled()) {
                logger.trace("Invoking init method  '" + initMethodName + "' on bean with name '" + beanName + "'");
            }
            Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);
    
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    ReflectionUtils.makeAccessible(methodToInvoke);
                    return null;
                });
                try {
                    AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
                            () -> methodToInvoke.invoke(bean), getAccessControlContext());
                }
                catch (PrivilegedActionException pae) {
                    InvocationTargetException ex = (InvocationTargetException) pae.getException();
                    throw ex.getTargetException();
                }
            }
            else {
                try {
                    ReflectionUtils.makeAccessible(methodToInvoke);
                    methodToInvoke.invoke(bean);
                }
                catch (InvocationTargetException ex) {
                    throw ex.getTargetException();
                }
            }
        }

    invokeCustomInitMethod 方法调用中,首先得到Bean定义的initMethod方法,然后通过JDK的反射得到Method对象,直接调用在Bean定义中声明的初始化方法。

    -4》 调用applyBeanPostProcessorsAfterInitialization 方法处理BeanPostProcessor 的postProcessAfterInitialization 代码逻辑。 需要注意PreDestroy 注解生命的会在这个里面做处理,对应的Processor是CommonAnnotationBeanPostProcessor

        @Override
        public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
                throws BeansException {
    
            Object result = existingBean;
            for (BeanPostProcessor processor : getBeanPostProcessors()) {
                Object current = processor.postProcessAfterInitialization(result, beanName);
                if (current == null) {
                    return result;
                }
                result = current;
            }
            return result;
        }

    (4) IoC容器使用Bean

    (5) Bean的销毁

    上面容器的销毁中 destroyBeans 是销毁Bean,经过一系列的调用会调到:org.springframework.beans.factory.support.DisposableBeanAdapter#destroy

        @Override
        public void destroy() {
            if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
                for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
                    processor.postProcessBeforeDestruction(this.bean, this.beanName);
                }
            }
    
            if (this.invokeDisposableBean) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
                }
                try {
                    if (System.getSecurityManager() != null) {
                        AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                            ((DisposableBean) this.bean).destroy();
                            return null;
                        }, this.acc);
                    }
                    else {
                        ((DisposableBean) this.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 methodToInvoke = determineDestroyMethod(this.destroyMethodName);
                if (methodToInvoke != null) {
                    invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
                }
            }
        }

    首先调用  postProcessBeforeDestruction,然后调用Bean的destroy方法,最后是对Bean的自定义销毁方法的调用,和前面初始化的过程类型。

    测试如下:

    UserDao:

    package cn.qz.user;
    
    import org.springframework.stereotype.Component;
    
    @Component
    public class UserDao {
    
        public void test1() {
        }
    }

    UserService:

    package cn.qz.user;
    import org.springframework.beans.factory.BeanNameAware;
    import org.springframework.beans.factory.DisposableBean;
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    
    //@Component
    //@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
    //@Lazy
    public class UserService implements InitializingBean, DisposableBean, BeanNameAware {
    
        // 构造
        public UserService() {
            System.out.println("=============UserService=====");
        }
    
        @Autowired
        public void setUserDao(UserDao userDao) {
            System.out.println("cn.qz.user.UserService.setUserDao====userDao");
        }
    
        // aware 接口
        @Override
        public void setBeanName(String name) {
            System.out.println("====setBeanName====" + name);
        }
    
        @PostConstruct
        public void PostConstruct() {
            System.out.println("PostConstruct =============");
        }
    
        // InitializingBean
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("====afterPropertiesSet====");
        }
    
        // initMethod
        public void initMethod() {
            System.out.println("====initMethod====");
        }
    
        @PreDestroy
        public void PreDestroy() {
            System.out.println("PreDestroy  =============");
        }
    
        // DisposableBean
        @Override
        public void destroy() throws Exception {
            System.out.println("====destroy====");
        }
    
        // destroyMethod
        public void destroyMethod() {
            System.out.println("====destroyMethod====");
        }
    
    }

    配置类:

    package cn.qz.user;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class BeanConfiguration {
    
        @Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
        public UserService userService() {
            return new UserService();
        }
    }

    编程式IoC如下:

    package cn.qz;
    
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.ComponentScan;
    
    @ComponentScan
    //@Import({ImpConfiguration.class})
    //@EnableAspectJAutoProxy
    public class App {
        public static void main(String[] args) {
            //在指定目录下生成动态代理类,我们可以反编译看一下里面到底是一些什么东西
    //        System.setProperty("cglib.debugLocation", "F:/proxy");
    
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(App.class);
            applicationContext.close();
        }
    }

    结果:

    =============UserService=====
    cn.qz.user.UserService.setUserDao====userDao
    ====setBeanName====userService
    PostConstruct =============
    ====afterPropertiesSet====
    ====initMethod====
    PreDestroy  =============
    ====destroy====
    ====destroyMethod====

    总结:其生命周期图如下:

     (1) Aware 接口的实现顺序为:BeanNameAware-》BeanClassLoaderAware-》BeanFactoryAware

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods

        private void invokeAwareMethods(String beanName, Object bean) {
            if (bean instanceof Aware) {
                if (bean instanceof BeanNameAware) {
                    ((BeanNameAware) bean).setBeanName(beanName);
                }
                if (bean instanceof BeanClassLoaderAware) {
                    ClassLoader bcl = getBeanClassLoader();
                    if (bcl != null) {
                        ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
                    }
                }
                if (bean instanceof BeanFactoryAware) {
                    ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
                }
            }
        }

    (2) ApplicationContextAwareProcessor 是一个特殊的BeanPostProcessor, 里面主要是增加了ApplicationContext 的一些相关Aware

    class ApplicationContextAwareProcessor implements BeanPostProcessor {
    
        private final ConfigurableApplicationContext applicationContext;
    
        private final StringValueResolver embeddedValueResolver;
    
    
        /**
         * Create a new ApplicationContextAwareProcessor for the given context.
         */
        public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
            this.applicationContext = applicationContext;
            this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
        }
    
    
        @Override
        @Nullable
        public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
            AccessControlContext acc = null;
    
            if (System.getSecurityManager() != null &&
                    (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
                            bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
                            bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
                acc = this.applicationContext.getBeanFactory().getAccessControlContext();
            }
    
            if (acc != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    invokeAwareInterfaces(bean);
                    return null;
                }, acc);
            }
            else {
                invokeAwareInterfaces(bean);
            }
    
            return bean;
        }
    
        private void invokeAwareInterfaces(Object bean) {
            if (bean instanceof Aware) {
                if (bean instanceof EnvironmentAware) {
                    ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
                }
                if (bean instanceof EmbeddedValueResolverAware) {
                    ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
                }
                if (bean instanceof ResourceLoaderAware) {
                    ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
                }
                if (bean instanceof ApplicationEventPublisherAware) {
                    ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
                }
                if (bean instanceof MessageSourceAware) {
                    ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
                }
                if (bean instanceof ApplicationContextAware) {
                    ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
                }
            }
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) {
            return bean;
        }
    
    }

    (3) 在容器的BeanPostProcessor 中有几个全局的非常有用的类:(Spring 默认的一些BeanPostProcessor)

    3.  BeanPostProcessor 的实现

     BeanPostProcessor是一个Bean的后置处理器,它可以监听容器触发的事件。将它向IoC容器注册后,容器中管理的Bean具备了接收IoC容器事件回调的能力。接口提供两个方法,一个是postProcessBeforeInitialization 在Bean的初始化之前提供回调入口;还有一个是postProcessAfterInitialization 在Bean的初始化之后提供回调入口。这两个回调都和容器管理Bean的生命周期相关。回调方法的参数都是一样的,分别是Bean的实例化对象和Bean的名字。

    如下:

    package org.springframework.beans.factory.config;
    
    import org.springframework.beans.BeansException;
    import org.springframework.lang.Nullable;
    
    
    public interface BeanPostProcessor {
    
        @Nullable
        default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            return bean;
        }
    
        @Nullable
        default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            return bean;
        }
    
    }

    两个方法的调用都是在doCreateBean方法的initializeBean 方法调用时调用

    (1)  org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

        protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
                throws BeanCreationException {
    
            // Instantiate the bean.
            BeanWrapper instanceWrapper = null;
            if (mbd.isSingleton()) {
                instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
            }
            if (instanceWrapper == null) {
                instanceWrapper = createBeanInstance(beanName, mbd, args);
            }
            Object bean = instanceWrapper.getWrappedInstance();
            Class<?> beanType = instanceWrapper.getWrappedClass();
            if (beanType != NullBean.class) {
                mbd.resolvedTargetType = beanType;
            }
    
            // Allow post-processors to modify the merged bean definition.
            synchronized (mbd.postProcessingLock) {
                if (!mbd.postProcessed) {
                    try {
                        applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                    }
                    catch (Throwable ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Post-processing of merged bean definition failed", ex);
                    }
                    mbd.postProcessed = true;
                }
            }
    
            // Eagerly cache singletons to be able to resolve circular references
            // even when triggered by lifecycle interfaces like BeanFactoryAware.
            boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                    isSingletonCurrentlyInCreation(beanName));
            if (earlySingletonExposure) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Eagerly caching bean '" + beanName +
                            "' to allow for resolving potential circular references");
                }
                addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
            }
    
            // Initialize the bean instance.
            Object exposedObject = bean;
            try {
                populateBean(beanName, mbd, instanceWrapper);
                exposedObject = initializeBean(beanName, exposedObject, mbd);
            }
            catch (Throwable ex) {
                if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
                    throw (BeanCreationException) ex;
                }
                else {
                    throw new BeanCreationException(
                            mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
                }
            }
    
            if (earlySingletonExposure) {
                Object earlySingletonReference = getSingleton(beanName, false);
                if (earlySingletonReference != null) {
                    if (exposedObject == bean) {
                        exposedObject = earlySingletonReference;
                    }
                    else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                        String[] dependentBeans = getDependentBeans(beanName);
                        Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                        for (String dependentBean : dependentBeans) {
                            if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                                actualDependentBeans.add(dependentBean);
                            }
                        }
                        if (!actualDependentBeans.isEmpty()) {
                            throw new BeanCurrentlyInCreationException(beanName,
                                    "Bean with name '" + beanName + "' has been injected into other beans [" +
                                    StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                                    "] in its raw version as part of a circular reference, but has eventually been " +
                                    "wrapped. This means that said other beans do not use the final version of the " +
                                    "bean. This is often the result of over-eager type matching - consider using " +
                                    "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                        }
                    }
                }
            }
    
            // Register bean as disposable.
            try {
                registerDisposableBeanIfNecessary(beanName, bean, mbd);
            }
            catch (BeanDefinitionValidationException ex) {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
            }
    
            return exposedObject;
        }

    (2) org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean

        protected Object initializeBean(String beanName, 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()) {
                wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
            }
    
            try {
                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;
        }
    
        @Override
        public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
                throws BeansException {
    
            Object result = existingBean;
            for (BeanPostProcessor processor : getBeanPostProcessors()) {
                Object current = processor.postProcessBeforeInitialization(result, beanName);
                if (current == null) {
                    return result;
                }
                result = current;
            }
            return result;
        }
    
        @Override
        public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
                throws BeansException {
    
            Object result = existingBean;
            for (BeanPostProcessor processor : getBeanPostProcessors()) {
                Object current = processor.postProcessAfterInitialization(result, beanName);
                if (current == null) {
                    return result;
                }
                result = current;
            }
            return result;
        }

    从上面代码可以看到,这两个Bean后置处理器定义的接口方法,一前一后,围绕着Bean定义的init-method方法调用。

    测试如下:

    package qz;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.stereotype.Component;
    
    /**
     * @author: 乔利强
     * @date: 2021/2/19 15:47
     * @description:
     */
    @Component
    public class MyPostProcessor implements BeanPostProcessor {
    
        // Bean的初始化之前提供回调入口
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            if ("userService".equals(beanName)) {
                System.out.println("====postProcessBeforeInitialization====");
            }
            return bean;
        }
    
        // Bean的初始化之后提供回调入口
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if ("userService".equals(beanName)) {
                System.out.println("====postProcessAfterInitialization====");
            }
            return bean;
        }
    }

    结果:

    =============UserService=====
    ====setBeanName====userService
    ====postProcessBeforeInitialization====
    PostConstruct =============
    ====afterPropertiesSet====
    ====initMethod====
    ====postProcessAfterInitialization====
    PreDestroy  =============
    ====destroy====
    ====destroyMethod====

    补充: BeanPostProcessor  的两个方法的返回值可以是以下三种情况

    bean-不对IoC生成的bean做处理,原封不动的返回

    proxrTarget-代理对象。也就是生成Cglib代理或者是JDK代理对象。 这对于接口类型接收的对象是可以的。(AOP代理对象的生成也是在BeanPostProcessor  中返回代理对象来修改引用完成的)

    null 返回一个空对象

    4. Aware的使用

      容器管理的Bean一般不需要了解容器的状态和直接使用容器,但在某些情况下,是需要在Bean中直接对IoC容器操作的,这时候就需要设定对容器的感知。SpringIoC容器也提供了该功能,通过特定的Aware接口实现。 

     在设置Bean的属性之后,调用初始化回调方法之前,Spring会调用sware接口的setter方法。

    org.springframework.context.support.ApplicationContextAwareProcessor 作为BeanPostProcessor 的实现,对一系列的aware 回调进行了调用

    class ApplicationContextAwareProcessor implements BeanPostProcessor {
    
        private final ConfigurableApplicationContext applicationContext;
    
        private final StringValueResolver embeddedValueResolver;
    
    
        /**
         * Create a new ApplicationContextAwareProcessor for the given context.
         */
        public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
            this.applicationContext = applicationContext;
            this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
        }
    
    
        @Override
        @Nullable
        public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
            AccessControlContext acc = null;
    
            if (System.getSecurityManager() != null &&
                    (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
                            bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
                            bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
                acc = this.applicationContext.getBeanFactory().getAccessControlContext();
            }
    
            if (acc != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    invokeAwareInterfaces(bean);
                    return null;
                }, acc);
            }
            else {
                invokeAwareInterfaces(bean);
            }
    
            return bean;
        }
    
        private void invokeAwareInterfaces(Object bean) {
            if (bean instanceof Aware) {
                if (bean instanceof EnvironmentAware) {
                    ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
                }
                if (bean instanceof EmbeddedValueResolverAware) {
                    ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
                }
                if (bean instanceof ResourceLoaderAware) {
                    ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
                }
                if (bean instanceof ApplicationEventPublisherAware) {
                    ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
                }
                if (bean instanceof MessageSourceAware) {
                    ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
                }
                if (bean instanceof ApplicationContextAware) {
                    ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
                }
            }
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) {
            return bean;
        }
    
    }

    ApplicationContextAwareProcessor 注入到Spring的时机是在org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory 准备IoC环境时。org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory 如下:

        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());
            }
        }

     测试:

    package qz;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.*;
    import org.springframework.context.*;
    import org.springframework.core.io.ResourceLoader;
    
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    
    //@Component
    //@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
    //@Lazy
    public class UserService implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware, ApplicationContextAware, MessageSourceAware, ApplicationEventPublisherAware, ResourceLoaderAware {
    
        // 构造
        public UserService() {
            System.out.println("=============UserService=====");
        }
    
        // BeanNameAware====可以在Bean中得到它在IoC容器中的Bean实例名称
        @Override
        public void setBeanName(String name) {
            System.out.println("====setBeanName====" + name);
        }
    
        // BeanFactoryAware====可以得到Bean所在的IoC容器,从而直接在Bean中石油IoC容器的服务
        @Override
        public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
            System.out.println("====beanFactory====" + beanFactory.getClass());
        }
    
        // ApplicationContextAware====可以在Bean得到Bean所在的应用上下文
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            System.out.println("====ApplicationContextAware====" + applicationContext.getClass());
        }
    
        // MessageSourceAware ==== 在Bean中得到消息源
        @Override
        public void setMessageSource(MessageSource messageSource) {
            System.out.println("====setMessageSource====" + messageSource.getClass());
        }
    
        // ApplicationEventPublisherAware ==== 在Bean中得到应用上下文的事件发布器,从而可以在Bean中发布应用上下文的事件
        @Override
        public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
            System.out.println("====setApplicationEventPublisher====" + applicationEventPublisher.getClass());
        }
    
        // ResourceLoaderAware ==== 在Bean中得到ResourceLoader,从而在Bean中使用ResourceLoader 加载外部对应的Resource资源
        @Override
        public void setResourceLoader(ResourceLoader resourceLoader) {
            System.out.println("====setResourceLoader====" + resourceLoader.getClass());
        }
    
        @PostConstruct
        public void PostConstruct() {
            System.out.println("PostConstruct =============");
        }
    
        // InitializingBean
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("====afterPropertiesSet====");
        }
    
        // initMethod
        public void initMethod() {
            System.out.println("====initMethod====");
        }
    
        @PreDestroy
        public void PreDestroy() {
            System.out.println("PreDestroy  =============");
        }
    
        // DisposableBean
        @Override
        public void destroy() throws Exception {
            System.out.println("====destroy====");
        }
    
        // destroyMethod
        public void destroyMethod() {
            System.out.println("====destroyMethod====");
        }
    }

    结果:

    =============UserService=====
    ====setBeanName====userService
    ====beanFactory====class org.springframework.beans.factory.support.DefaultListableBeanFactory
    ====setResourceLoader====class org.springframework.context.annotation.AnnotationConfigApplicationContext
    ====setApplicationEventPublisher====class org.springframework.context.annotation.AnnotationConfigApplicationContext
    ====setMessageSource====class org.springframework.context.annotation.AnnotationConfigApplicationContext
    ====ApplicationContextAware====class org.springframework.context.annotation.AnnotationConfigApplicationContext
    ====postProcessBeforeInitialization====
    PostConstruct =============
    ====afterPropertiesSet====
    ====initMethod====
    ====postProcessAfterInitialization====
    PreDestroy  =============
    ====destroy====
    ====destroyMethod====

    补充:FactoryBean 满足Bean 的生命周期,创建、属性注入、初始化(调用Aware接口、BeanPostProcessor.postProcessBeforeInitialization、InitializingBean.afterPropertiesSet、invokeCustomInitMethod、BeanPostProcessor.postProcessAfterInitialization)、使用、销毁。但是FactoryBean 的getObject 方法生成的对象不会走生命流程。

    并且在IoC 过程中初始化单例对象时不会创建对象工厂getObject 创建的对象,对象工厂生成的对象只会在第一次使用getBean 获取时才会创建。

    我们知道对于factoryBean, &beanName 获取factory 对象自身,beanName 获取其生成的getObject 对象

    测试:

    Test 类:

    package cn.qz.factorybean;
    
    import org.springframework.beans.factory.BeanClassLoaderAware;
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    import org.springframework.context.ResourceLoaderAware;
    import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
    import org.springframework.core.io.ResourceLoader;
    import org.springframework.core.type.AnnotationMetadata;
    
    public class Test implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, BeanClassLoaderAware {
    
        public Test() {
            System.out.println("Test=====0");
        }
    
        @Override
        public void setBeanClassLoader(ClassLoader classLoader) {
            System.out.println("Test=====1");
        }
    
        @Override
        public void setResourceLoader(ResourceLoader resourceLoader) {
            System.out.println("Test=====2");
        }
    
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            System.out.println("Test=====3");
        }
    }

    TestFactoryBean:

    package cn.qz.factorybean;
    
    import org.springframework.beans.factory.BeanClassLoaderAware;
    import org.springframework.beans.factory.FactoryBean;
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.context.ResourceLoaderAware;
    import org.springframework.core.io.ResourceLoader;
    
    public class TestFactoryBean implements FactoryBean<Test>, ResourceLoaderAware, BeanClassLoaderAware, InitializingBean {
    
        public TestFactoryBean() {
            System.out.println("TestFactoryBean created===1");
        }
    
        @Override
        public Test getObject() throws Exception {
            return new Test();
        }
    
        @Override
        public Class<?> getObjectType() {
            return Test.class;
        }
    
        @Override
        public void setBeanClassLoader(ClassLoader classLoader) {
            System.out.println("TestFactoryBean created===2");
        }
    
        @Override
        public void setResourceLoader(ResourceLoader resourceLoader) {
            System.out.println("TestFactoryBean created===3");
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("TestFactoryBean created===4");
        }
    }

    主类:

    package cn.qz;
    
    import cn.qz.factorybean.Test;
    import cn.qz.factorybean.TestFactoryBean;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.Import;
    
    @Import({TestFactoryBean.class})
    public class App {
    
        public App() {
            System.out.println("App created ======");
        }
    
        public static void main(String[] args) {
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(App.class);
            Test bean = applicationContext.getBean(Test.class);
            System.out.println(bean);
            applicationContext.close();
        }
    
    }

    结果

    App created ======
    TestFactoryBean created===1
    TestFactoryBean created===2
    TestFactoryBean created===3
    TestFactoryBean created===4
    Test=====0
    cn.qz.factorybean.Test@1b1473ab

    applicationContext.getBean(Test.class);代码跟踪:

    1》org.springframework.context.support.AbstractApplicationContext#getBean(java.lang.Class<T>)

    2》org.springframework.beans.factory.support.DefaultListableBeanFactory#getBean(java.lang.Class<T>)

    3》org.springframework.beans.factory.support.DefaultListableBeanFactory#getBean(java.lang.Class<T>, java.lang.Object...)

    4》org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveBean

    5》org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveNamedBean(org.springframework.core.ResolvableType, java.lang.Object[], boolean)

    org.springframework.beans.factory.support.DefaultListableBeanFactory#getBeanNamesForType(org.springframework.core.ResolvableType)  获取合适的beanname

    上面方法调用org.springframework.beans.factory.support.DefaultListableBeanFactory#getBeanNamesForType(java.lang.Class<?>, boolean, boolean) 获取适用的beanName

    上面方法调用org.springframework.beans.factory.support.DefaultListableBeanFactory#doGetBeanNamesForType    这里遍历factorybean,调用 Class<?> getObjectType(); 根据这个类型进行类型的判断

    获取的适用的beanName为:

    6》 获取到对应的beanName之后调用(beanName 是工厂的名称,requiredType类型是工厂生成的对象类型)。org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String, java.lang.Class<T>, java.lang.Object...)

    7》org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

    首先获取到对象工厂对象调用org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstance

    调用org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getObjectFromFactoryBean 从对象工厂获取对象

    org.springframework.beans.factory.support.FactoryBeanRegistrySupport#doGetObjectFromFactoryBean 直接调用对象的getObject 方法

    【当你用心写完每一篇博客之后,你会发现它比你用代码实现功能更有成就感!】
  • 相关阅读:
    C# 按笔画排序
    WEB EXCEL OWC开发(老资料)
    JS操作Cookie
    汉字转拼音缩写取首字母
    javaScript通用数据类型校验
    嵌套Repeater 子层获得父层字段值 经典!!!
    不同于其他的provider: SQL 网络接口, error: 26 定位指定的服务器/实例时出错
    C# UDP 发送 接收
    Js 过滤空格
    高亮文本框
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/14415269.html
Copyright © 2011-2022 走看看