Spring-IOC源码解析
Spring-IOC源码解析
本文我们主要关注下面三点
- IOC是什么
- IoC的好处
- IOC的实现原理
一.IOC是什么
我们都知道spring的核心技术有AOP和IOC,Ioc(Inversion of Control)
字面意思即“控制反转”,是一种设计思想而已。最常见的方式被称作依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。
那么控制反转 是谁控制了谁?又是什么进行了反转呢?
1:谁控制谁?
在没有IOC的时候,我们的JAVA程序只能在册程序内部进行依赖对象的创建。IOC运用了IOC容器去创建这些依赖对象的创建,所以是IOC控制了对象,控制了外部依赖的获取
2:什么反转了呢?
在没有IOC的时候,我们的JAVA程序只能在对象的内部主动获取依赖对象,而反转是由容器来帮忙创建及注入依赖对象,所以是依赖对象的获取方式反转了,由主动变被动。
二.IoC的好处
面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”
传统程序都是由我们在类内部主动创建依赖对象,则会导致类类之间高耦合。
有了IoC容器后,把依赖对象的控制权交给了容器,由容器进行注入,所以对象与对象之间是松散耦合,利于功能复用,更重要的是使得程序的整个结构体系变得灵活。
二.IoC的实现原理
2.1 首先我们介绍一下IOC的核心组件
1.BeanFactory
public interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&";
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
boolean containsBean(String name);
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
String[] getAliases(String name);
}
BeanFactory 是一个最核心最核心的接口,这是IOC容器的接口定义。
如果IOC是一把枪的话,那么BeanFactory就定义了这把枪的基本功比如枪可以安装子弹,扣动扳机,发射子弹等功能
SpringBean的创建是典型的工厂模式,在Spring中有许多的IOC容器的实现供用户选择和使用它定义了IOC容器的基本功能,由它的实现类拓展以及进行功能的实现,相互关系如下
BeanFactory 有三个子类:ListableBeanFactory、HierarchicalBeanFactory 和AutowireCapableBeanFactory。
ListableBeanFactory 接口表示这些 Bean 是可列表的
HierarchicalBeanFactory 表示的是这些 Bean 是有继承关系的
AutowireCapableBeanFactory 接口定义 Bean 的自动装配规则
这四个接口共同定义了 Bean 的集合、Bean 之间的关系、以及 Bean 行为
BeanFactory 最终的默认实现类是 DefaultListableBeanFactory,他实现了所有的接口,其上层各种接口主要是为了区分在 Spring 内部在操作过程中对象的传递和转化过程中,对象的数据访问所做的限制。
2.ApplicationContext
ApplicationContext是Spring提供的一个高级的IoC容器,它基IoC容器的基本功能,另外提供了以下的增强服务。
1. 支持信息源,可以实现国际化。(实现MessageSource接口)
2. 访问资源。(实现ResourcePatternResolver接口,这个后面要讲)
3. 支持应用事件。(实现ApplicationEventPublisher接口)
引用BeanFactory例子 如果IOC是一把枪的话,那么BeanFactory就定义了这把枪的基本功比如枪可以安装子弹,扣动扳机,发射子弹等功能,当然ApplicationContext就是一把更牛X的枪,比如增加了瞄准镜,消音器等功能
3.BeanDefinition
2.2 搭建简单的IOC例子
下面我们搭建一个spirng maven 项目
userService.java
package com.zes.spring.ioc;
public class UserService {
public void getUser() {
System.out.println("query user from DB");
}
}
application.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean name="userService" class="com.zes.spring.ioc.UserService"></bean>
</beans>
Test.java
package com.zes.spring.ioc;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
UserService userService = (UserService) context.getBean("userService");
userService.getUser();
}
}
运行Test.main 可以在控制台中打印 query user from DB
2.3 源码分析
我们通过 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(“application.xml”);
创建了一个容器,就可以用了,那么容器的创建过程是怎么样的,以及我们的UserService是以什么样的身份何时被配置到IOC中的呢?又是如何取出的呢?
我们点进去调用的ClassPathXmlApplicationContext的构造方法看下
public ClassPathXmlApplicationContext(String... configLocations) throws BeansException {
this(configLocations, true, (ApplicationContext)null);
}
可以看出构造方法被重载了,可以看到该构造方法被重载了,可以传递 configLocation 数组。
也就是说,可以传递过个配置文件的地址。默认刷新为true,parent 容器为null。进入另一个构造器:
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
super(parent);
this.setConfigLocations(configLocations);
if (refresh) {
this.refresh();
}
}
该构造器一是设置配置文件,二是刷新容器,我们不难猜出,refresh 方法才是初始化容器的最关键方法。
我们进入这个方法,这个方法是 ClassPathXmlApplicationContext 的父类AbstractXmlApplicationContext 的父类AbstractRefreshableConfigApplicationContext 的父类AbstractRefreshableApplicationContext的父类AbstractApplicationContext 的方法。
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
// 为刷新准备应用上下文
this.prepareRefresh();
//刷新子类工厂,在子类中refreshBeanFactory()的地方创建bean工厂,根据配置文件生成bean定义
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
// 在这个上下文中使用bean工厂
this.prepareBeanFactory(beanFactory);
try {
// 设置BeanFactory的后置处理器
postProcessBeanFactory(beanFactory);
// 调用BeanFactory的后处理器,这些后处理器是在Bean定义中向容器注册的
invokeBeanFactoryPostProcessors(beanFactory);
// 注册Bean的后处理器,在Bean创建过程中调用
registerBeanPostProcessors(beanFactory);
//对上下文的消息源进行初始化
initMessageSource();
// 初始化上下文中的事件机制
initApplicationEventMulticaster();
// 初始化其他的特殊Bean
onRefresh();
// 检查监听Bean并且将这些Bean向容器注册
registerListeners();
// 实例化所有的(non-lazy-init)单件
finishBeanFactoryInitialization(beanFactory);
// 发布容器事件,结束refresh过程
finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
// 异常情况便销毁bean
this.destroyBeans();
// 把 this.active.set(false);
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
这段代码就是spring IOC初始化的所有逻辑,基本思想逻辑包含五步
我们看第一步构建BeanFactory的业务逻辑 this.obtainFreshBeanFactory方法
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
this.refreshBeanFactory();
return this.getBeanFactory();
}
这个方法调用了 this.refreshBeanFactory()方法,返回一个ConfigurableListableBeanFactory
refreshBeanFactory是模板方法由AbstractRefreshableApplicationContext具体实现我们看代码实现
protected final void refreshBeanFactory() throws BeansException {
if (this.hasBeanFactory()) {
// 如果已经有就销毁并关闭
this.destroyBeans();
this.closeBeanFactory();
}
try {
//创建一个DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = this.createBeanFactory();
//序列化
beanFactory.setSerializationId(this.getId());
// 定制的BeanFactory
this.customizeBeanFactory(beanFactory);
// 加载bean
this.loadBeanDefinitions(beanFactory);
Object var2 = this.beanFactoryMonitor;
synchronized(this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch (IOException var5) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
}
}
这里有个很重要的方法, this.loadBeanDefinitions(beanFactory);
可以看出这是加载BeanDefinitions的方法,Definition是bean被包装过后的身份,是ioc中的对象的数据结构。
这个方法也是抽象的,默认实现在AbstractXmlApplicationContext 当中,我们找到对应的代码
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//构造一个 XmlBeanDefinitionReader 用于读取xml文件
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
//设置环境
beanDefinitionReader.setEnvironment(this.getEnvironment());
// 设置资源加载器
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// 最后两行用于加载BeanDefinitions
this.initBeanDefinitionReader(beanDefinitionReader);
this.loadBeanDefinitions(beanDefinitionReader);
}
其中loadBeanDefinitions是核心代码,我们看源码
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
// 得到配置文件
Resource[] configResources = this.getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = this.getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
~~~~~~~~~~~回忆第一步我们在ClassPathXmlApplicationContext的构造方法已经看到,把文件("application.xml")路径塞到了
this.setConfigLocations(configLocations)这个方法。所以这里会略过第一个判断继续执行 遍历configLocations数组。
通过配置文件循环加载BeanDefinitions ,我们继续看loadBeanDefinitions方法。
@Override
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
Assert.notNull(locations, "Location array must not be null");
int count = 0;
for (String location : locations) {
count += loadBeanDefinitions(location);
}
return count;
}
======================================
很明显没有我们想看的,继续点进去loadBeanDefinitions方法,进入了AbstractBeanDefinitionReader类的loadBeanDefinitions方法
====================================
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
// 获取到资源加载器
ResourceLoader resourceLoader = getResourceLoader();
if (resourceLoader == null) {
throw new BeanDefinitionStoreException(
"Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
}
if (resourceLoader instanceof ResourcePatternResolver) {
// Resource pattern matching available.
try {
// 获取到文件资源数组
Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
// 加载loadBeanDefinitions
int count = loadBeanDefinitions(resources);
if (actualResources != null) {
Collections.addAll(actualResources, resources);
}
if (logger.isTraceEnabled()) {
logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
}
return count;
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"Could not resolve bean definition resource pattern [" + location + "]", ex);
}
}
else {
// Can only load single resources by absolute URL.
Resource resource = resourceLoader.getResource(location);
int count = loadBeanDefinitions(resource);
if (actualResources != null) {
actualResources.add(resource);
}
if (logger.isTraceEnabled()) {
logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
}
return count;
}
}
===========继续点loadBeanDefinitions方法进入XmlBeanDefinitionReader类
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (logger.isTraceEnabled()) {
logger.trace("Loading XML bean definitions from " + encodedResource);
}
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet<>(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
try {
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
finally {
inputStream.close();
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
}
finally {
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
===========继续点doLoadBeanDefinitions方法
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
Document doc = doLoadDocument(inputSource, resource);
int count = registerBeanDefinitions(doc, resource);
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + count + " bean definitions from " + resource);
}
return count;
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (SAXParseException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
}
catch (SAXException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"XML document from " + resource + " is invalid", ex);
}
catch (ParserConfigurationException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Parser configuration exception parsing XML from " + resource, ex);
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"IOException parsing XML document from " + resource, ex);
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Unexpected exception parsing XML document from " + resource, ex);
}
}
该方法主要逻辑是根据输入流加载 Document 文档对象,然后根据得到的文档对象注册到容器
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
// 核心
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
首先创建了一个BeanDefinitionDocumentReader 继续进入registerBeanDefinitions方法
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
文档解析 最终调用了parseDefaultElement方法。感觉我们已进入一个无底洞,不急。5分钟抽根烟…继续点进去
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
// BEAN_ELEMENT = "bean";
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}
所以我们继续进入processBeanDefinition方法
/**
* Process the given bean element, parsing the bean definition
* and registering it with the registry.
*/
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
首先得到了一个BeanDefinitionHolder,然后调用了BeanDefinitionReaderUtils.registerBeanDefinition 方法
最后
/**
* Register the given bean definition with the given bean factory.
* @param definitionHolder the bean definition including name and aliases
* @param registry the bean factory to register with
* @throws BeanDefinitionStoreException if registration failed
*/
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
从BeanDefinitionHolder拿到beanname 和BeanDefinition 塞入registerBeanDefinition方法
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
//
=====================注意==========================
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
我们终于走到了最后一步 this.beanDefinitionMap.put(beanName, beanDefinition);
/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
这个是用来存储bean对象的map
结尾的流程我们知道了 那么beanDefinition我们没有看他的实现逻辑,还记得刚才我抽的那根烟么? 抽完之后我们进入了
processBeanDefinition方法,我们看这句话
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
parseBeanDefinitionElement 干了什么
好吧!!!!
该方法又调用了
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
/**
* Parse the bean definition itself, without regard to name or aliases. May return
* {@code null} if problems occurred during the parsing of the bean definition.
*/
@Nullable
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, @Nullable BeanDefinition containingBean) {
this.parseState.push(new BeanEntry(beanName));
String className = null;
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
String parent = null;
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
try {
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
parseMetaElements(ele, bd);
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
parseConstructorArgElements(ele, bd);
parsePropertyElements(ele, bd);
parseQualifierElements(ele, bd);
bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));
return bd;
}
catch (ClassNotFoundException ex) {
error("Bean class [" + className + "] not found", ele, ex);
}
catch (NoClassDefFoundError err) {
error("Class that bean class [" + className + "] depends on not found", ele, err);
}
catch (Throwable ex) {
error("Unexpected failure during bean definition parsing", ele, ex);
}
finally {
this.parseState.pop();
}
return null;
}
取出了className 然后createBeanDefinition(className, parent)
最终调用了BeanDefinitionReaderUtils.createBeanDefinition 方法
/**
* Create a bean definition for the given class name and parent name.
* @param className the name of the bean class
* @param parentName the name of the bean's parent bean
* @return the newly created bean definition
* @throws ClassNotFoundException if bean class resolution was attempted but failed
*/
protected AbstractBeanDefinition createBeanDefinition(@Nullable String className, @Nullable String parentName)
throws ClassNotFoundException {
return BeanDefinitionReaderUtils.createBeanDefinition(
parentName, className, this.readerContext.getBeanClassLoader());
}
BeanDefinitionReaderUtils.createBeanDefinition如下
/**
* Create a new GenericBeanDefinition for the given parent name and class name,
* eagerly loading the bean class if a ClassLoader has been specified.
* @param parentName the name of the parent bean, if any
* @param className the name of the bean class, if any
* @param classLoader the ClassLoader to use for loading bean classes
* (can be {@code null} to just register bean classes by name)
* @return the bean definition
* @throws ClassNotFoundException if the bean class could not be loaded
*/
public static AbstractBeanDefinition createBeanDefinition(
@Nullable String parentName, @Nullable String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException {
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setParentName(parentName);
if (className != null) {
if (classLoader != null) {
bd.setBeanClass(ClassUtils.forName(className, classLoader));
}
else {
bd.setBeanClassName(className);
}
}
return bd;
}
/
GenericBeanDefinition继承了AbstractBeanDefinition 。class类信息放进去就结束了
此时我们的bean工厂构造完成,以及bean信息也定义好了,还没有进行bean的实例化
在我们分析源码的开始refresh()中 有一步骤为
finishBeanFactoryInitialization(beanFactory);
这个方法有一步骤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.
// 首先将bean difinition放到一个新的集合中。
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()) {
//是否为FactoryBean,不是的话直接实例化
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());
}
// 如果是FactoryBean,判断FactoryBean有没有其他的的配置
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
// 触发所有应用Bean的post-initialization 回调
for (String beanName : beanNames) {
//获取Bean的实例
Object singletonInstance = getSingleton(beanName);
// 如果实例实现了SmartInitializingSingleton,执行afterSingletonsInstantiated方法。
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
smartSingleton.afterSingletonsInstantiated();
return null;
}
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
getBean -> doGetBean
protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = this.transformedBeanName(name);//解析beanName 因为如果是FactoryBean会带上&符号
Object sharedInstance = this.getSingleton(beanName);//尝试从缓存中获取单例bean
Object bean;
if(sharedInstance != null && args == null) {//如果已经存在
·····
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);//主要是对FactoryBean进行处理
} else {
BeanFactory ex = this.getParentBeanFactory();
if(ex != null && !this.containsBeanDefinition(beanName)) {//父bean工厂进行生产
String var24 = this.originalBeanName(name);
if(args != null) {
return ex.getBean(var24, args);
}
return ex.getBean(var24, requiredType);
}
if(!typeCheckOnly) {
this.markBeanAsCreated(beanName);//把bean添加到标识准备好创建的list
}
try {
final RootBeanDefinition ex1 = this.getMergedLocalBeanDefinition(beanName);// 生成简单beanDefintion
this.checkMergedBeanDefinition(ex1, beanName, args);
String[] dependsOn = ex1.getDependsOn();//获取它的依赖bean
String[] scopeName;
if(dependsOn != null) {
scopeName = dependsOn;
int scope = dependsOn.length;
for(int ex2 = 0; ex2 < scope; ++ex2) {//循环生产所依赖的bean
String dependsOnBean = scopeName[ex2];
this.getBean(dependsOnBean);
this.registerDependentBean(dependsOnBean, beanName);//注册到依赖bean集合
}
}
if(ex1.isSingleton()) {//判断是否单例
sharedInstance = this.getSingleton(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
try {
return AbstractBeanFactory.this.createBean(beanName, ex1, args);//真正生成bean的方法,这里会对循环依赖问题进行处理
} catch (BeansException var2) {
AbstractBeanFactory.this.destroySingleton(beanName);
throw var2;
}
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, ex1);
} else if(ex1.isPrototype()) {
scopeName = null;
Object var25;
try {
this.beforePrototypeCreation(beanName);
var25 = this.createBean(beanName, ex1, args);
} finally {
this.afterPrototypeCreation(beanName);
}
bean = this.getObjectForBeanInstance(var25, name, beanName, ex1);
} else {
String var26 = ex1.getScope();
Scope var27 = (Scope)this.scopes.get(var26);
if(var27 == null) {
throw new IllegalStateException("No Scope registered for scope \'" + var26 + "\'");
}
try {
Object var28 = var27.get(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
AbstractBeanFactory.this.beforePrototypeCreation(beanName);
Object var1;
try {
var1 = AbstractBeanFactory.this.createBean(beanName, ex1, args);
} finally {
AbstractBeanFactory.this.afterPrototypeCreation(beanName);
}
return var1;
}
});
bean = this.getObjectForBeanInstance(var28, name, beanName, ex1);
} catch (IllegalStateException var21) {
throw new BeanCreationException(beanName, "Scope \'" + var26 + "\' is not active for the current thread; " + "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var21);
}
}
} catch (BeansException var23) {
this.cleanupAfterBeanCreationFailure(beanName);
throw var23;
}
}
if(requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
try {
return this.getTypeConverter().convertIfNecessary(bean, requiredType);
} catch (TypeMismatchException var22) {
if(this.logger.isDebugEnabled()) {
this.logger.debug("Failed to convert bean \'" + name + "\' to required type [" + ClassUtils.getQualifiedName(requiredType) + "]", var22);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
} else {
return bean;
}
}
===
public Object getSingleton(String beanName, ObjectFactory singletonFactory) {
Map var3 = this.singletonObjects;
synchronized(this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if(singletonObject == null) {
···
try {
singletonObject = singletonFactory.getObject();//获取bean
} catch (BeanCreationException var14) {
BeanCreationException ex = var14;
if(recordSuppressedExceptions) {
Iterator i$ = this.suppressedExceptions.iterator();
while(i$.hasNext()) {
Exception suppressedException = (Exception)i$.next();
ex.addRelatedCause(suppressedException);
}
}
throw ex;
} finally {
if(recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
}
this.addSingleton(beanName, singletonObject);//添加到单例缓存map
}
return singletonObject != NULL_OBJECT?singletonObject:null;
}
}
==
```
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
this.resolveBeanClass(mbd, beanName, new Class[0]);
try {
mbd.prepareMethodOverrides();
} catch (BeanDefinitionValidationException var5) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "Validation of method overrides failed", var5);
}
Object beanInstance;
try {
beanInstance = this.resolveBeforeInstantiation(beanName, mbd);//开始初始化工作
if(beanInstance != null) {
return beanInstance;
}
} catch (Throwable var6) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var6);
}
beanInstance = this.doCreateBean(beanName, mbd, args);//生产bean
if(this.logger.isDebugEnabled()) {
this.logger.debug("Finished creating instance of bean \'" + beanName + "\'");
}
return beanInstance;
}
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if(!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
if(mbd.hasBeanClass() && !mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
bean = this.applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName);//对实现InstantiationAwareBeanPostProcessor接口的bean进行初始化
if(bean != null) {
bean = this.applyBeanPostProcessorsAfterInitialization(bean, beanName);//执行beanPostProcessor的AfterInitialization方法
}
}
mbd.beforeInstantiationResolved = Boolean.valueOf(bean != null);
}
return bean;
}
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Object[] args) {
BeanWrapper instanceWrapper = null;
if(mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if(instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper != null?instanceWrapper.getWrappedInstance():null;
Class beanType = instanceWrapper != null?instanceWrapper.getWrappedClass():null;
Object earlySingletonExposure = mbd.postProcessingLock;
synchronized(mbd.postProcessingLock) {
if(!mbd.postProcessed) {
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);//对实现MergedBeanDefinitionPostProcessor接口的bean进行处理
mbd.postProcessed = true;
}
}
boolean var19 = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if(var19) {
if(this.logger.isDebugEnabled()) {
this.logger.debug("Eagerly caching bean \'" + beanName + "\' to allow for resolving potential circular references");
}
this.addSingletonFactory(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
return AbstractAutowireCapableBeanFactory.this.getEarlyBeanReference(beanName, mbd, bean);
}
});
}
Object exposedObject = bean;
try {
this.populateBean(beanName, mbd, instanceWrapper);//设置属性
if(exposedObject != null) {
exposedObject = this.initializeBean(beanName, exposedObject, mbd);//初始化bean 先执行BeanPostProcessor的BeforeInitialization方法 然后如果这个bean实现了InitializingBean接口则执行afterPropertiesSet方法 然后执行init-method方法 最后执行BeanPostProcessor的AfterInitialization方法
}
} catch (Throwable var17) {
if(var17 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var17).getBeanName())) {
throw (BeanCreationException)var17;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var17);
}
if(var19) {
Object ex = this.getSingleton(beanName, false);
if(ex != null) {
if(exposedObject == bean) {
exposedObject = ex;
} else if(!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
String[] dependentBeans = this.getDependentBeans(beanName);
LinkedHashSet actualDependentBeans = new LinkedHashSet(dependentBeans.length);
String[] arr$ = dependentBeans;
int len$ = dependentBeans.length;
for(int i$ = 0; i$ < len$; ++i$) {
String dependentBean = arr$[i$];
if(!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if(!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName, "Bean with name \'" + beanName + "\' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "\'getBeanNamesOfType\' with the \'allowEagerInit\' flag turned off, for example.");
}
}
}
}
try {
this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
} catch (BeanDefinitionValidationException var16) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
}
}
```
end