• 09-spring的bean创建流程(一)


    spring中bean的创建流程

    finishBeanFactoryInitialization(beanFactory)

    在refresh方法中知道此方法就是初始化剩下的单实例

    				// Instantiate all remaining (non-lazy-init) singletons.
    				// 初始化剩下的单实例(非懒加载的)
    				finishBeanFactoryInitialization(beanFactory);
    
    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    		// Initialize conversion service for this context.
    		// 为上下文初始化类型转换器
    		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
    				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
    			beanFactory.setConversionService(
    					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    		}
    
    		// Register a default embedded value resolver if no bean post-processor
    		// (such as a PropertyPlaceholderConfigurer bean) registered any before:
    		// at this point, primarily for resolution in annotation attribute values.
    		// 如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器,主要用于注解属性值的解析
    		if (!beanFactory.hasEmbeddedValueResolver()) {
    			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    		}
    
    		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
    		// 尽早初始化loadTimeWeaverAware bean,以便尽早注册它们的转换器
    		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    		for (String weaverAwareName : weaverAwareNames) {
    			getBean(weaverAwareName);
    		}
    
    		// Stop using the temporary ClassLoader for type matching.
    		// 禁止使用临时类加载器进行类型匹配
    		beanFactory.setTempClassLoader(null);
    
    		// Allow for caching all bean definition metadata, not expecting further changes.
    		// 冻结所有的bean定义,说明注册的bean定义将不被修改或任何进一步的处理
    		beanFactory.freezeConfiguration();
    
    		// Instantiate all remaining (non-lazy-init) singletons.
    		// 实例化剩下的单例对象
    		beanFactory.preInstantiateSingletons();
    	}
    

    首先是初始化类型转换器,此转换器在spring mvc中较多,后续具体再看,这里的主要逻辑是获取名为conversionService类型为ConversionService.class的bean,使用此bean对对象做一个转换服务。
    可以自定义实现这样的转换

    public class Student {
    
        private Integer id;
        private String name;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
    
    import org.springframework.core.convert.converter.Converter;
    
    public class StudentConverter implements Converter<String,Student> {
        @Override
        public Student convert(String source) {
            System.out.println("-----");
            Student s  = new Student();
            String[] splits = source.split("_");
            s.setId(Integer.parseInt(splits[0]));
            s.setName(splits[1]);
            return s;
        }
    }
    

    beanFactory.preInstantiateSingletons();

    此方法是实例化剩下的单例对象

    public void preInstantiateSingletons() throws BeansException {
    		if (logger.isTraceEnabled()) {
    			logger.trace("Pre-instantiating singletons in " + this);
    		}
    
    		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
    		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
    		// 将所有BeanDefinition的名字创建一个集合
    		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    
    		// Trigger initialization of all non-lazy singleton beans...
    		// 触发所有非延迟加载单例bean的初始化,遍历集合的对象
    		for (String beanName : beanNames) {
    			// 合并父类BeanDefinition
     			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    			// 条件判断,抽象,单例,非懒加载
    			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
    				// 判断是否实现了FactoryBean接口
    				if (isFactoryBean(beanName)) {
    					// 根据&+beanName来获取具体的对象
    					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
    					// 进行类型转换
    					if (bean instanceof FactoryBean) {
    						FactoryBean<?> factory = (FactoryBean<?>) bean;
    						// 判断这个FactoryBean是否希望立即初始化
    						boolean isEagerInit;
    						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
    							isEagerInit = AccessController.doPrivileged(
    									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
    									getAccessControlContext());
    						}
    						else {
    							isEagerInit = (factory instanceof SmartFactoryBean &&
    									((SmartFactoryBean<?>) factory).isEagerInit());
    						}
    						//  如果希望急切的初始化,则通过beanName获取bean实例
    						if (isEagerInit) {
    							getBean(beanName);
    						}
    					}
    				}
    				else {
    					// 如果beanName对应的bean不是FactoryBean,只是普通的bean,通过beanName获取bean实例
    					getBean(beanName);
    				}
    			}
    		}
    
    		// Trigger post-initialization callback for all applicable beans...
    		// 遍历beanNames,触发所有SmartInitializingSingleton的后初始化回调
    		for (String beanName : beanNames) {
    			// 获取beanName对应的bean实例
    			Object singletonInstance = getSingleton(beanName);
    			// 判断singletonInstance是否实现了SmartInitializingSingleton接口
    			if (singletonInstance instanceof SmartInitializingSingleton) {
    				// 类型转换
    				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
    				// 触发SmartInitializingSingleton实现类的afterSingletonsInstantiated方法
    				if (System.getSecurityManager() != null) {
    					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    						smartSingleton.afterSingletonsInstantiated();
    						return null;
    					}, getAccessControlContext());
    				}
    				else {
    					smartSingleton.afterSingletonsInstantiated();
    				}
    			}
    		}
    	}
    

    getMergedLocalBeanDefinition(beanName);流程

    此方法是合并父类BeanDefinition,这里面使用了递归处理
    流程如下
    在这里插入图片描述

    实现FactoryBean接口,里面的对象实例化过程

    if (isFactoryBean(beanName)) {
    					// 根据&+beanName来获取具体的对象
    					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
    					// 进行类型转换
    					if (bean instanceof FactoryBean) {
    						FactoryBean<?> factory = (FactoryBean<?>) bean;
    						// 判断这个FactoryBean是否希望立即初始化
    						boolean isEagerInit;
    						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
    							isEagerInit = AccessController.doPrivileged(
    									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
    									getAccessControlContext());
    						}
    						else {
    							isEagerInit = (factory instanceof SmartFactoryBean &&
    									((SmartFactoryBean<?>) factory).isEagerInit());
    						}
    						//  如果希望急切的初始化,则通过beanName获取bean实例
    						if (isEagerInit) {
    							getBean(beanName);
    						}
    					}
    				}
    

    何为FactoryBean?他与BeanFactory有什么区别
    先看FactoryBean的类的结构,此接口里面仅有getObject()、getObjectType()、isSingleton()这三个方法,使用这个类将实例注入到bean工厂中,不需要严格遵循BeanFactory里面bean的构建流程(初始化、实例化、aware接口、前置处理、后置处理),可以在FactoryBean中直接调用getObject()直接生成bean对象,并放入到factoryBeanObjectCache集合中,此集合是个Map。没有放到三级缓存中。后续如果需要则从factoryBeanObjectCache这个集合中获取。
    特别:非单例情况下,实例始终不会往factoryBeanObjectCache中放,即非单例不会有缓存

    如何实现FactoryBean

    public class MyFactoryBean implements FactoryBean<User> {
    
        @Override
        public User getObject() throws Exception {
            return new User("zhangsan");
        }
    
        @Override
        public Class<?> getObjectType() {
            return User.class;
        }
    
        @Override
        public boolean isSingleton() {
            return false;
        }
    }
    
    
    public class User {
    
        private String username;
    
        public User() {
        }
    
        public User(String username) {
            this.username = username;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "username='" + username + '\'' +
                    '}';
        }
    }
    

    当上面的逻辑处理完成时(这里粗略的看就是refresh方法完成),这时FactoryBean中已经有实现了FactoryBean的bean了,但是里面的对现象还没有放入到缓存中,如果这个类实现了SmartFactoryBean这个接口,并重写了isEagerInit方法,将其返回为true。那么在实例化FactoryBean这个对象的时候,里面的对象也会实例化并放入到factoryBeanObjectCache缓存中(非单例情况下,实例始终不会往factoryBeanObjectCache中放,即非单例不会有缓存)。这里没有实现SmartFactoryBean,只是实现了FactoryBean,所以没有直接实例化,而是在调用的时候进行的实例化。
    实现流程
    在这里插入图片描述

  • 相关阅读:
    ArGIS Engine专题(13)之矢量要素图层符号化(单一符号化渲染)
    SQL电商面试题:如何分析复杂业务?
    linux 硬盘存储剩余容量自动化监控+报警通知
    基于Python实现的SVM实验
    C#实现最大公约数和最小公倍数
    抖音API接口汇总及解析式(网络爬虫)
    前端工程化精讲第四课 接口调试:Mock 工具如何快速进行接口调试?
    时间轴_打印机
    vue项目本地开发构建速度优化 hard-source-webpack-plugin
    让开发者成为决定性力量,华为开发者英雄汇圆满落幕
  • 原文地址:https://blog.csdn.net/zql1455890112/article/details/139460586