zoukankan      html  css  js  c++  java
  • 【spring源码解读】spring加载流程refresh之prepareBeanFactory(beanFactory)

    【spring源码解读】spring加载流程refresh之prepareBeanFactory(beanFactory)

    一:介绍prepareBeanFactory

    spring启动的核心流程都是在org.springframework.context.support.AbstractApplicationContext这个抽象类的refresh()方法中。

    prepareBeanFactory(beanFactory)是刷新流程中的第三个方法。

    这个方法的主要内容。

    二:主要作用

    第一步加载类加载器

    beanFactory.setBeanClassLoader(getClassLoader());

    第二步:设置一个解析器StandardBeanExpressionResolver

    这个是设置spring el表达式的实现;

    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    

    第三步:添加PropertyEditor属性编辑器,这里可以自定义属性编辑器,比如我们在注入一个日期字符串,spring的默认解析器没有办法解析,就可以自定义属性解析器。

    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    

    注入处理注入propertis文件的。

    @Service
    public class PropertiesDemo {
    
    	@Value("classpath:test.properties")
    	private Resource properties;
    
    	public Resource getProperties() {
    		return properties;
    	}
    
    	public void setProperties(Resource properties) {
    		this.properties = properties;
    	}
    }
    

    在classpath目录下增加一个properties

    执行后的结果,properties文件中的内容注入到了我们的Resource对象中。

    第四步:这里加BeanPostProcessorApplicationContextAwareProcessor实现类,这个方法主要在加载bean的时候进行。主要是这个方法,BeanPostProcessor 后面简称BBP。

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

    这个逻辑简单,就是设置bean的一些感知接口。

    第五步:忽略一些bean的,注入比如一些aware感知接口,这些都是因为在前面注入的ApplicationContextAwareProcessor中通过setter注入。

    	    /**
    		 * 跳过以下6个属性的自动注入
    		 */
    		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    

    第六步:注册一个bbp(BeanPostProcessor)ApplicationListenerDetector,这个bbp主要是注册监听器,代码在下图所示。

    第六步:这是添加一个处理aop的bbp。

           // 判断存在AOP bean name 则注册aop前置处理器
    		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()));
    		}
    

    第七步:这一步主要添加一些模式环境变量

    		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());
    		}
    
  • 相关阅读:
    搭建zabbix监控
    liunx 下ctrl+D问题解决方案
    linux配置双线策略
    Discuz! X2.5读写分离
    慢谈MYSQL常用SQL语句
    CentOS 6.5系统安装配置LAMP(Apache+PHP5+MySQL)服务器环境
    自动抓包shell脚本
    zabbix实施部署原理架构
    ftp搭建教程
    DNS搭建教程
  • 原文地址:https://www.cnblogs.com/simple-flw/p/14773842.html
Copyright © 2011-2022 走看看