前言:
本文较长,源码部分已经只查看主枝,如果阅读本文,希望打开idealJ穿透源码阅读更加容易理解。
正文:
一、举例:
写一个简单的ioc依赖注入
1.1、写一个简单的Bean:
public class SpringTest {
public static void main(String[] args){
ApplicationContext context = new ClassPathXmlApplicationContext("conf/test-bean.xml");
TestBean testBean = (TestBean) context.getBean("tBean");
System.out.println("----------------"+testBean.toString()+"----------------");
}
}
1.2、Bean模型如下:
public class TestBean {
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "TestBean{" +
"name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
}
1.3、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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="tBean" class="com.haibo.future.web.test.TestBean">
<property name="name" value="haibo666"/>
<property name="password" value="666pwd"/>
</bean>
</beans>
1.4、结果如下:
TestBean{name='haibo666', password='666pwd'}
二、源码分析总纲:
2.1、根据xml配置生成ApplicationContext实例:
ApplicationContext context = new ClassPathXmlApplicationContext("conf/test-bean.xml");
2.2、根据上面生成的ApplicationContext实例获取/生成需要的Bean实例对象:
TestBean testBean = (TestBean) context.getBean("tBean");
三、ioc依赖注入思路:
依赖注入主要发生在2.1代码位置:流程如下
conf/test-bean.xml个人配置——》生成FactoryBean的定义模版——》通过FactoryBean模版生成实例化对象——》对象注入属性值
四、源码分析(粗略)
先看一个类图ApplicationContext:可以知道ApplicationContext接口继承自BeanFactory:也就是生成ApplicationContext实例就是生成一个BeanFactory对象。
先看2.1的代码:
ApplicationContext context = new ClassPathXmlApplicationContext("conf/test-bean.xml");
跟进代码,查看ClassPathXmlApplicationContext构造方法
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
备注一:其中setConfigLocations:AbstractRefreshableConfigApplicationContext#configLocations属性赋值。
主要关注第二个方法refresh:这个方法很重要。后称 代码零
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
略
}
finally {
略
}
}
}
简化版代码零:上述代码简化如下:只剩下2行代码(只读骨架不深究其它)
// Tell the subclass to refresh the internal bean factory.
//1、根据xml生成BeanFactory模版
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Instantiate all remaining (non-lazy-init) singletons.
//2、根据BeanFactory模版生成实例bean对象
finishBeanFactoryInitialization(beanFactory);
五、源码分析(详细):根据xml生成BeanFactory模版
简化版代码零:obtainFreshBeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
代码说明:
这个代码比较容易理解。
第2行:生成/刷新BeanFactory模版;
第3行:将返回值指向上面生成的beanFactory模版(主要后续会通过这个beanFactory生成实例)。
所以,我只需要看第2行代码就可以。
第2行代码:refreshBeanFactory
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
第一块代码(if hasBeanFactory判断处):如果以前存在beanFactory就关闭。此处可忽略。
第二块DefaultListableBeanFactory beanFactory = createBeanFactory();创建了一个DefaultListableBeanFactory实例。也就是BeanFactory实例,并未给属性赋值。此处以后代称 代码一
直接看这行代码:loadBeanDefinitions(beanFactory);见名知意:加载Bean的定义,也就是我所说的生成BeanFactory模版。
子类的loadBeanDefinitions:
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with this context's
// resource loading environment.
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
其中生成了一个xmlBeanDefinitionReader:可以理解为新建了一个通过xml生成Bean的模版的输入流实例。
最后一行loadBeanDefinitions:
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
然后经过一系列的同名方法loadBeanDefinitions:(后续会分析这一系列同名载入bean模版主要做了些什么)
最终会到达XmlBeanDefinitionReader#loadBeanDefinitions:
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
略
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();
}
}
略
}
其中这一行代码生成了一个输入流:
InputStream inputStream = encodedResource.getResource().getInputStream();
有人可能会问encodedResource哪来的?
之前一系列的loadBeanDefinitions同名方法中存在这样的转换
从一个加载xml文件而来:主要为以下两个操作;
(1)location---》resource
(2)resource---》EncodedResource:而这个就是上面的encodedResource。
操作(1)部分代码如下
Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
int loadCount = loadBeanDefinitions(resources);
操作(2)部分代码如下
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
return loadBeanDefinitions(new EncodedResource(resource));
}
回到之前代码:看看对输入流做了什么操作。
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
其中doLoadBeanDefinitions:此处代码非常重要。重要的事说三遍!非常重要!非常重要!非常重要!
此处根据我们自己的xml---》转换成流---》生成了一个Document对象。Document可以理解为一个文档树的根,并提供对文档树的访问。
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
Document doc = doLoadDocument(inputSource, resource);
return registerBeanDefinitions(doc, resource);
}
catch (xxException ex) {
略
}
}
registerBeanDefinitions:就是文档树Document对象—》BeanDefinitionDocumentReader :
即将Document的每一个叶子节点都注册为一个Bean模版。
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;
}
跟进此处registerBeanDefinitions:
@Override
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
logger.debug("Loading bean definitions");
Element root = doc.getDocumentElement();
doRegisterBeanDefinitions(root);
}
跟进此处doRegisterBeanDefinitions:
protected void doRegisterBeanDefinitions(Element root) {
略
preProcessXml(root);
parseBeanDefinitions(root, this.delegate);
postProcessXml(root);
略
}
跟进此处parseBeanDefinitions:
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);
}
}
到此我们获得了解析Document的某一个元素的方法:默认标签解析和自定义标签的解析(我们只分析默认标签解析方法)parseDefaultElement:对应四种默认标签import,alias,bean,beans,是否非常熟悉?
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}
查看其中最常见最小的bean解析代码processBeanDefinition:
代码二
此处分解成两个操作:
1、解析document的元素element成为一个Bean定义模版BeanDefinitionHolder;
2、将这个Bean定义模版BeanDefinitionHolder注册到BeanDefinitionReaderUtils;
注册到此处BeanDefinitionReaderUtils到底注册到哪了?实际是给DefaultListableBeanFactory的两个属性赋值。
先分析第一个操作:1、解析document的元素element成为一个Bean定义模版BeanDefinitionHolder;
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));
}
}
第2行代码:解析bean的具体代码如下:
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
String id = ele.getAttribute(ID_ATTRIBUTE);
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
List<String> aliases = new ArrayList<String>();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
}
String beanName = id;
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
beanName = aliases.remove(0);
if (logger.isDebugEnabled()) {
logger.debug("No XML 'id' specified - using '" + beanName +
"' as bean name and " + aliases + " as aliases");
}
}
if (containingBean == null) {
checkNameUniqueness(beanName, aliases, ele);
}
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
if (beanDefinition != null) {
if (!StringUtils.hasText(beanName)) {
try {
if (containingBean != null) {
beanName = BeanDefinitionReaderUtils.generateBeanName(
beanDefinition, this.readerContext.getRegistry(), true);
}
else {
beanName = this.readerContext.generateBeanName(beanDefinition);
// Register an alias for the plain bean class name, if still possible,
// if the generator returned the class name plus a suffix.
// This is expected for Spring 1.2/2.0 backwards compatibility.
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null &&
beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}
if (logger.isDebugEnabled()) {
logger.debug("Neither XML 'id' nor 'name' specified - " +
"using generated bean name [" + beanName + "]");
}
}
catch (Exception ex) {
error(ex.getMessage(), ele);
return null;
}
}
String[] aliasesArray = StringUtils.toStringArray(aliases);
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
return null;
}
首先获得id和name属性,然后如果有别名如何处理,如果不是别名,则生成一个bean自定义模版:
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
返回模版对象:
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
再分析第二个操作:2、将这个Bean定义模版BeanDefinitionHolder注册到BeanDefinitionReaderUtils;
用上述代码得到的这个bean的模版对象,注册到BeanDefinitionReaderUtils:
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
PS:其中registerBeanDefinition究竟注册到哪了呢?继续跟进代码:
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);
}
}
}
注册最后到此registerBeanDefinition:
关键代码为以下2行设置属性。将beanName(bean名称)和beanDefinition(bean模版)属性赋值。
这两个值赋值也就是给DefaultListableBeanFactory赋值。饶了一大圈就是为了赋值DefaultListableBeanFactory的这两个属性,回看代码一可知此处DefaultListableBeanFactory的主要赋值已经完成:即根据我们xml文件生成的beanFactory模版已经完成。
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
略
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
略
}
ok,BeanFactory模版生成,属性配好,留作后用。
六、源码分析(详细):根据BeanFactory模版生成实例bean对象及依赖注入属性值
回到简化版代码零,查看代码零中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));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
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.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
跟进最后1行代码beanFactory.preInstantiateSingletons():BeanFactory模版实例化(非懒加载的实例)。
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);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
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();
}
}
}
}
1、DefaultListableBeanFactory#beanDefinitionNames(BeanFactory模版定义源码分析最后已对该属性赋值)获得beanName的列表:List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
2、beanName非抽象,是单例模式,不是懒加载---》beanName是factoryBean,则生成factoryBean实例。如果beanName不是factoryBean类型,则执行getBean(beanName);
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
doGetBean此处代码量有些大,但逻辑还是很清晰:大概意思就是根据不同条件生成Bean对象。
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dependsOnBean : dependsOn) {
if (isDependent(beanName, dependsOnBean)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
}
registerDependentBean(dependsOnBean, beanName);
getBean(dependsOnBean);
}
}
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' 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",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type [" +
ClassUtils.getQualifiedName(requiredType) + "]", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
大概流程如下:
1、别名判断final String beanName = transformedBeanName(name);,别名则解析为真实名称。
2、Object sharedInstance = getSingleton(beanName);查看单例对象是否已经被实例化来判断是否需要实例化。如果不需要实例化,则直接从缓存中获取bean对象。
3、需要实例化,则继续。BeanFactory parentBeanFactory = getParentBeanFactory();检查是否存在父工厂类对象存在。存在,则从父类工厂对象获取bean对象。
4、String[] dependsOn = mbd.getDependsOn();检查需要生成bean依赖关系,如果存在依赖,则先生成依赖对象bean。没有,则继续。
5、在DefaultListableBeanFactory#beanDefinitionMap中已经建立了beanName和BeanFactory(此处为RootBeanDefinition)的关系。通过final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);获取到BeanFactory定义模版。
当BeanFactory定义模版mbd是单例模式的时候,直接尝试获取实例化对象。
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
}
});
直接从Object singletonObject = this.singletonObjects.get(beanName);尝试获取实例化对象,如果获取到则直接返回,没获取到,则需要Override的getObject方法中创建Bean实例的方法createBean(beanName, mbd, args);此处已经用到BeanFactroy模版和BeanName生成Bean对象。
6、mdb非单例模式,是原型的时候,其代码判断为mbd.isSingleton():创建BeanFactory模版的实例,代码如prototypeInstance = createBean(beanName, mbd, args);
7、mdb其它类型,调用自动装配工厂产生该bean对象的实例。createBean(beanName, mbd, args)
既然5、6、7步都是调用创建方法:createBean(beanName, mbd, args)根据Beanfactory模型创建bean对象。跟进createBean(beanName, mbd, args)如下:
AbstractAutowireCapableBeanFactory#createBean
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
略
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
略
return beanInstance;
}
跟进doCreateBean方法:一大波代码,简化后如下,
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
略
// Initialize the bean instance.
Object exposedObject = bean;
略
return exposedObject;
}
很清晰的直接看到创建Bean对象代码instanceWrapper = createBeanInstance(beanName, mbd, args);只留下主干代码。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName);
略
// Need to determine the constructor...
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
操作1:如果有构造方法,及构造方法属性值等,则获得构造方法的定义,实例化bean对象并注入属性值。autowireConstructor(beanName, mbd, ctors, args);
操作2:其它,则默认初始化bean。instantiateBean(beanName, mbd);
操作1 具体代码分析:
跟进autowireConstructor到ConstructorResolver#autowireConstructor:
public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
Constructor<?>[] chosenCtors, final Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
此处略去参数组装代码一大堆
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
final Constructor<?> ctorToUse = constructorToUse;
final Object[] argumentsToUse = argsToUse;
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
return beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, beanFactory, ctorToUse, argumentsToUse);
}
}, beanFactory.getAccessControlContext());
}
else {
beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
bw.setWrappedInstance(beanInstance);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via constructor failed", ex);
}
}
最终都到这个代码处生成bean对象实例:
beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
跟进代码instantiate方法:
此处有两种生成Object的方式先看第一种:BeanFactory定义中,方法覆盖为空的时候——》BeanUtils.instantiateClass(ctor, args) 代称代码三
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner,
final Constructor<?> ctor, Object... args) {
if (bd.getMethodOverrides().isEmpty()) {
if (System.getSecurityManager() != null) {
// use own privileged to change accessibility (when security is on)
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
ReflectionUtils.makeAccessible(ctor);
return null;
}
});
}
return BeanUtils.instantiateClass(ctor, args);
}
else {
return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
}
}
跟进instantiateClass方法代码:看到构造方法的newInstance,其中构造方法的参数为args。
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
return ctor.newInstance(args);
}
catch (XXException ex) {
略
}
}
操作2具体代码分析:
跟进instantiateBean方法:
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
return getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
}, getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
两分支都最终进入同一个初始化代码块,跟进getInstantiationStrategy().instantiate(mbd, beanName, parent)代码:
此处有两种生成Object的方式先看第一种:BeanFactory定义中,方法覆盖为空的时候——》BeanUtils.instantiateClass(ctor, args)
@Override
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (bd.getMethodOverrides().isEmpty()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
@Override
public Constructor<?> run() throws Exception {
return clazz.getDeclaredConstructor((Class[]) null);
}
});
}
else {
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Exception ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
同构造方法的初始化bean,最后也是调用BeanUtils.instantiateClass(constructorToUse)。
上面两次提到“BeanFactory定义中,方法覆盖为空的时候——》BeanUtils.instantiateClass(ctor, args) ”,回到代码三,现在看另一个分支,当方法覆盖不为空的时候,执行instantiateWithMethodInjection(bd, beanName, owner, ctor, args):
@Override
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, String beanName, BeanFactory owner,
Constructor<?> ctor, Object... args) {
// Must generate CGLIB subclass...
return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
}
跟进instantiate代理的这个方法:方法很简单,也是在构造方法时注入的args属性。
public Object instantiate(Constructor<?> ctor, Object... args) {
Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
Object instance;
if (ctor == null) {
instance = BeanUtils.instantiate(subclass);
}
else {
try {
Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
instance = enhancedSubclassConstructor.newInstance(args);
}
catch (Exception ex) {
throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
}
}
// SPR-10785: set callbacks directly on the instance instead of in the
// enhanced class (via the Enhancer) in order to avoid memory leaks.
Factory factory = (Factory) instance;
factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
return instance;
}
本文完,感谢阅读,望指正。