【简记】Java Web 内幕——Spring中Bean的创建(源码摘录)
2017-07-10 18:23
519 查看
本章内容:
Bean的创建
构建Bean的关系网
http://www.cnblogs.com/xrq730/p/6361578.html
这里先解释一下getMergedLocalBeanDefinition方法的含义,因为这个方法会常常看到。Bean定义公共的抽象类是AbstractBeanDefinition,普通的Bean在Spring加载Bean定义的时候,实例化出来的是GenericBeanDefinition,而Spring上下文包括实例化所有Bean用的AbstractBeanDefinition是RootBeanDefinition,这时候就使用getMergedLocalBeanDefinition方法做了一次转化,将非RootBeanDefinition转换为RootBeanDefinition以供后续操作。
解释完了getMergedLocalBeanDefinition方法的作用,第1行~第10行的代码就没什么好说的了,根据beanName拿到RootBeanDefinition而已。由于此方法实例化的是所有非懒加载的单例Bean,因此要实例化Bean,必须满足11行的三个定义:
(1)不是抽象的
(2)必须是单例的
(3)必须是非懒加载的
接着简单看一下第12行~第29行的代码,这段代码主要做的是一件事情:首先判断一下Bean是否FactoryBean的实现,接着判断Bean是否SmartFactoryBean的实现,假如Bean是SmartFactoryBean的实现并且eagerInit(这个单词字面意思是渴望加载,找不到一个好的词语去翻译,意思就是定义了这个Bean需要立即加载的意思)的话,会立即实例化这个Bean。
这里出现了一个非常重要的Bean一Factory Bean ,可以说Spring 有一大半的扩展功能都与这个Bean 有关,这是个特殊的Bean 。它是个工厂Bean ,可以产生Bean的Bean ,这里的产生Bean 是指Bean 的实例,如果一个类继FactoryBean ,用户可以自己定义产生实例对象的方法,只需实现它的getObject 方法即可。然而在Spring 内部,这个Bean的实例对象是FactoryBean ,通过调用这个对象的getObject 方法就能获取用户自定义产生的对象,从而为Spring 提供了很好的扩展性。
以下是结合getBean方法的流程图:
createBeanInstance方法
创建出Bean的实例,并包装为BeanWrapper。BeanWrapper的作用,实现了设置和获取属性值的功能。
通过反射生成Bean的实例。看到前面有一步makeAccessible,意味着即使Bean的构造函数是private、protected的,依然不影响Bean的构造。
大致流程
Bean的创建
构建Bean的关系网
http://www.cnblogs.com/xrq730/p/6361578.html
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Stop using the temporary ClassLoader for type matching. beanFactory.setTempClassLoader(null); // Allow for caching all bean definition metadata, not expecting further changes. beanFactory.freezeConfiguration(); //实例化non-lazy-init 类型的bean beanFactory.preInstantiateSingletons(); }
public void preInstantiateSingletons() throws BeansException { if (this.logger.isDebugEnabled()) { this.logger.debug("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. List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName); boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { @Override public Boolean run() { return ((SmartFactoryBean<?>) factory).isEagerInit(); } }, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } else { getBean(beanName); } } }
这里先解释一下getMergedLocalBeanDefinition方法的含义,因为这个方法会常常看到。Bean定义公共的抽象类是AbstractBeanDefinition,普通的Bean在Spring加载Bean定义的时候,实例化出来的是GenericBeanDefinition,而Spring上下文包括实例化所有Bean用的AbstractBeanDefinition是RootBeanDefinition,这时候就使用getMergedLocalBeanDefinition方法做了一次转化,将非RootBeanDefinition转换为RootBeanDefinition以供后续操作。
解释完了getMergedLocalBeanDefinition方法的作用,第1行~第10行的代码就没什么好说的了,根据beanName拿到RootBeanDefinition而已。由于此方法实例化的是所有非懒加载的单例Bean,因此要实例化Bean,必须满足11行的三个定义:
(1)不是抽象的
(2)必须是单例的
(3)必须是非懒加载的
接着简单看一下第12行~第29行的代码,这段代码主要做的是一件事情:首先判断一下Bean是否FactoryBean的实现,接着判断Bean是否SmartFactoryBean的实现,假如Bean是SmartFactoryBean的实现并且eagerInit(这个单词字面意思是渴望加载,找不到一个好的词语去翻译,意思就是定义了这个Bean需要立即加载的意思)的话,会立即实例化这个Bean。
这里出现了一个非常重要的Bean一Factory Bean ,可以说Spring 有一大半的扩展功能都与这个Bean 有关,这是个特殊的Bean 。它是个工厂Bean ,可以产生Bean的Bean ,这里的产生Bean 是指Bean 的实例,如果一个类继FactoryBean ,用户可以自己定义产生实例对象的方法,只需实现它的getObject 方法即可。然而在Spring 内部,这个Bean的实例对象是FactoryBean ,通过调用这个对象的getObject 方法就能获取用户自定义产生的对象,从而为Spring 提供了很好的扩展性。
以下是结合getBean方法的流程图:
createBeanInstance方法
创建出Bean的实例,并包装为BeanWrapper。BeanWrapper的作用,实现了设置和获取属性值的功能。
通过反射生成Bean的实例。看到前面有一步makeAccessible,意味着即使Bean的构造函数是private、protected的,依然不影响Bean的构造。
大致流程
相关文章推荐
- 【简记】Java Web 内幕——Spring源码(组件分析,BeanFactory源码,Bean创建之前)
- 【简记】Java Web 内幕——SpringMVC总体介绍,部分源码解析
- 【简记】Java Web 内幕——AOP源码
- 使用反射创建Bean、Spring中是如何根据类名配置创建Bean实例、Java提供了Class类获取类别的字段和方法,包括构造方法
- 随web容器启动Java类,调用spring容器中的的bean及其方法
- Spring Boot 使用Java代码创建Bean并注册到Spring中
- Java Web 学习笔记(四) 基于 SpringMVC+BootStrap 创建WebApp
- spring 源码探索--创建bean实例和初始化
- Spring源码分析-2-创建Bean
- (41)Spring Boot 使用Java代码创建Bean并注册到Spring中【从零开始学Spring Boot】
- 从零开始的spring 之 脱离web下的spring 上 (javaconfig装配bean)
- 在使用hibernate 和spring 构架的框架中如果出现Initialization of bean failed; nested exception is java.lang.NoSuchMethodError: org.objectweb.asm
- 通过springboot+mybatis+mysql+freemarker创建一个java web项目
- 详解Spring Boot 使用Java代码创建Bean并注册到Spring中
- 【JavaWeb-23】spring、IoC控制反转和DI依赖注入入门、基于XML的Bean装配、基于注解的Bean装配
- Java Web开发框架Spring+Hibernate整合效果介绍(附源码)
- Java源码 SpringMVC Mybatis Shiro Bootstrap Rest Webservice
- Spring Boot 使用Java代码创建Bean并注册到Spring中
- Spring源码之bean的加载(五)准备创建bean
- 41. Spring Boot 使用Java代码创建Bean并注册到Spring中【从零开始学Spring Boot】