美文网首页我爱编程心情随笔
SpringBoot注解扩展篇(2)-BeanFactory的前

SpringBoot注解扩展篇(2)-BeanFactory的前

作者: Terminalist | 来源:发表于2018-06-10 17:27 被阅读1221次

    继续接着讲prepareBeanFactory()的流程,这一步的主要作用是BeanFactory的预准备工作,也就是对BeanFactory进行一些初始化后的设置;


    进入这个方法的实现之前,我们来看下方法上面的注释,Configure the factory's standard context characteristics, such as the context's ClassLoader and post-processors.翻译后的大概意思就是:设置这个BeanFactory的标准上下文特性,比如比如上下文的类加载器和后置处理器。传进来的参数是待配置的beanFactory。ok,看下其源码:

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        beanFactory.setBeanClassLoader(getClassLoader());
            beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
            beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
            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.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);
            beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    
            if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
                beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            
                beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
            }
    
            
            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());
            }
        }
    

    首先:
    1.设置BeanFactoryBeanClassLoader,如果存在,则直接使用之前的那个,否则,初始化一个新的ClassLoader;
    2.设置BeanExpressionResolver表达式解析器,主要用来解析EL表达式;那么什么时候会进行EL表达式的解析嘞?可以提前剧透下,也就是在Bean进行初始化后会有属性填充的一步,方法如下:

    protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
    
    ...
    
    //属性填充
    applyPropertyValues(beanName, mbd, bw, pvs);
    }
    
    

    在这一步中会调用BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter); 来进行属性值的解析;而接下来便是通过AbstractBeanFactory中的evaluateBeanDefinitionString方法进行解析,解析代码如下:

    protected Object evaluateBeanDefinitionString(String value, BeanDefinition beanDefinition) {
            if (this.beanExpressionResolver == null) {
                return value;
            }
            Scope scope = (beanDefinition != null ? getRegisteredScope(beanDefinition.getScope()) : null);
            return this.beanExpressionResolver.evaluate(value, new BeanExpressionContext(this, scope));
        }
    

    然后这时候就进到StandardBeanExpressionResolver中的evaluate方法中进行解析了;

    3.设置属性注册解析器PropertyEditor;这个主要是对某些注入的Bean的一些属性的支持;
    4.设置ApplicationContextAwareProcessor的支持,关于BeanPostProcessor的作用我这里不在赘述,在这个地方仅仅是注册,真是的实现还是在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(new PrivilegedAction<Object>() {
                    @Override
                    public Object run() {
                        invokeAwareInterfaces(bean);
                        return null;
                    }
                }, acc);
            }
            else {
                invokeAwareInterfaces(bean);
            }
    
            return bean;
        }
    

    首先就是校验权限,然后就是判断Aware的类型,然后调用invokeAwareInterfaces,这样实现了这些Aware接口的Bean在被初始化之后就能取到响应的资源.
    再看其后置处理器,啥事没干,直接返回Bean:

    public Object postProcessAfterInitialization(Object bean, String beanName) {
            return bean;
        }
    

    接下来就是设置忽略自动装配的属性:

    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
            beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
            beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
            beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
            beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
            beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    

    当Spring将ApplicationContextAwareProcessor注册后,已经注册了EnvironmentAware.class, EmbeddedValueResolverAware.class, ResourceLoaderAware.class, ApplicationEventPublisherAware.class,
    MessageSourceAware.class,
    ApplicationContextAware.class,
    这些内容,那么在Spring做Bean的注入的时候肯定是要忽略他们的;

    再往下走就是注册依赖了,这里没啥好说的,就是当检查到依赖时,将依赖的实例进行注册;
    接下来又是注册后置处理器ApplicationListenerDetector,这里主要是检测是否有事件监听;
    以及判断是否有对编译时AspectJ的支持,这些都是通过后置处理器来完成的,最后主要是给BeanFactory注册一些能通用的组件。

    好了,这一节内容不多,感觉自己说了好多废话,但是也是为了能将内容讲明白,不足之处望大街指出,下一节我们讲BeanFactory的后置处理,敬请期待!

    相关文章

      网友评论

        本文标题:SpringBoot注解扩展篇(2)-BeanFactory的前

        本文链接:https://www.haomeiwen.com/subject/ctqqeftx.html