• Spring扩展点之Aware接口族


    引言

    Spring中提供了各种Aware接口,方便从上下文中获取当前的运行环境,比较常见的几个子接口有:BeanFactoryAware,BeanNameAware,ApplicationContextAware,EnvironmentAware,BeanClassLoaderAware等,这些Aware的作用都可以从命名得知

    Aware处理

    其中BeanNameAwareBeanClassLoaderAwareBeanFactoryAware这三个是直接在bean的初始化之前就处理了的,具体代码在AbstractAutowireCapableBeanFactory.initializeBean方法中:

    protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
        // 判断对象实现的接口类型,处理特定的三种接口类型:BeanNameAware、BeanClassLoaderAware和BeanFactoryAware。
        if (bean instanceof BeanNameAware) {
            ((BeanNameAware) bean).setBeanName(beanName);
        }
     
        if (bean instanceof BeanClassLoaderAware) {
            ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
        }
     
        if (bean instanceof BeanFactoryAware) {
            ((BeanFactoryAware) bean).setBeanFactory(this);
        }
        // 开始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;
    }
    

    除了这三种之外的那些Aware接口的实现就不太一样了,它们都是利用BeanPostProcessor接口完成的,关于BeanPostProcessor接口的原理可以这篇文章:Spring扩展点之BeanPostProcessor

    ApplicationContextAware就是利用ApplicationContextAwareProcessor实现的:

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

    ApplicationContextAwareProcessor的注册奥秘在AbstractApplicationContext.prepareBeanFactory方法中:

    beanFactory.setBeanClassLoader(getClassLoader());
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this));
     beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); 
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    
  • 相关阅读:
    Xenserver中SR、VBD和VDI之间的关系
    rabbitmq镜像模式设置策略以及高可用
    MySQL主从复制配置详解
    xen 虚拟机挂了,宿主机假死的问题追终,全思路
    XenServer中备份正在运行的虚拟机
    理解 Docker 容器退出码
    prometheus 监控之 进程监控(processexporter)
    XenServer 常见故障处理
    httpCurl封装
    工作中不要为了用系统而用系统
  • 原文地址:https://www.cnblogs.com/zhixiang-org-cn/p/11531615.html
Copyright © 2020-2023  润新知