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

继续接着讲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() {
                @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的前置处理)