Spring IOC

Inversion of Control is a principle in software engineering by which the control of objects or portions of a program is transferred to a container or framework. It’s most often used in the context of object-oriented programming.
By contrast with traditional programming, in which our custom code makes calls to a library, IoC enables a framework to take control of the flow of a program and make calls to our custom code. To enable this, frameworks use abstractions with additional behavior built in. If we want to add our own behavior, we need to extend the classes of the framework or plugin our own classes.

前言

    Spring 容器是 Spring 框架的核心。容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁。Spring 容器使用依赖注入(DI)来管理组成一个应用程序的组件。

Spring 架构:


IoC 中最核心的接口是 BeanFactory 提供 IoC 的高级服务,而 ApplicationContext 是建立在 BeanFactory 基础之上提供抽象的面向应用的服务。BeanFactory 提供了配置框架和基本的功能,ApplicationContext 建立在 BeanFactory 之上,并增加了其他功能,一般来说,ApplicationContext 是 BeanFactory 的完全超集,任何 BeanFactory 功能和行为的描述也同样被认为适用于 ApplicationContext。

BeanFactory 继承树:


核心方法refresh()的具体步骤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
Spring容器的refresh()【创建刷新】;
1、prepareRefresh()刷新前的预处理;
1)、initPropertySources()初始化一些属性设置;子类自定义个性化的属性设置方法;
2)、getEnvironment().validateRequiredProperties();检验属性的合法等
3)、earlyApplicationEvents= new LinkedHashSet<ApplicationEvent>();保存容器中的一些早期的事件;
2、obtainFreshBeanFactory();获取BeanFactory;
1)、refreshBeanFactory();刷新【创建】BeanFactory;
创建了一个this.beanFactory = new DefaultListableBeanFactory();
设置id;
2)、getBeanFactory();返回刚才GenericApplicationContext创建的BeanFactory对象;
3)、将创建的BeanFactory【DefaultListableBeanFactory】返回;
3、prepareBeanFactory(beanFactory);BeanFactory的预准备工作(BeanFactory进行一些设置);
1)、设置BeanFactory的类加载器、支持表达式解析器...
2)、添加部分BeanPostProcessor【ApplicationContextAwareProcessor】
3)、设置忽略的自动装配的接口EnvironmentAware、EmbeddedValueResolverAware、xxx;
4)、注册可以解析的自动装配;我们能直接在任何组件中自动注入:
BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
5)、添加BeanPostProcessor【ApplicationListenerDetector】
6)、添加编译时的AspectJ;
7)、给BeanFactory中注册一些能用的组件;
environment【ConfigurableEnvironment】、
systemProperties【Map<String, Object>】、
systemEnvironment【Map<String, Object>】
4、postProcessBeanFactory(beanFactory);BeanFactory准备工作完成后进行的后置处理工作;
1)、子类通过重写这个方法来在BeanFactory创建并预准备完成以后做进一步的设置
======================以上是BeanFactory的创建及预准备工作==================================
5、invokeBeanFactoryPostProcessors(beanFactory);执行BeanFactoryPostProcessor的方法;
BeanFactoryPostProcessor:BeanFactory的后置处理器。在BeanFactory标准初始化之后执行的;
两个接口:BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor
1)、执行BeanFactoryPostProcessor的方法;
先执行BeanDefinitionRegistryPostProcessor
1)、获取所有的BeanDefinitionRegistryPostProcessor;
2)、看先执行实现了PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor、
postProcessor.postProcessBeanDefinitionRegistry(registry)
3)、在执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessor;
postProcessor.postProcessBeanDefinitionRegistry(registry)
4)、最后执行没有实现任何优先级或者是顺序接口的BeanDefinitionRegistryPostProcessors;
postProcessor.postProcessBeanDefinitionRegistry(registry)


再执行BeanFactoryPostProcessor的方法
1)、获取所有的BeanFactoryPostProcessor
2)、看先执行实现了PriorityOrdered优先级接口的BeanFactoryPostProcessor、
postProcessor.postProcessBeanFactory()
3)、在执行实现了Ordered顺序接口的BeanFactoryPostProcessor;
postProcessor.postProcessBeanFactory()
4)、最后执行没有实现任何优先级或者是顺序接口的BeanFactoryPostProcessor;
postProcessor.postProcessBeanFactory()
6、registerBeanPostProcessors(beanFactory);注册BeanPostProcessor(Bean的后置处理器)【 intercept bean creation】
不同接口类型的BeanPostProcessor;在Bean创建前后的执行时机是不一样的
BeanPostProcessor、
DestructionAwareBeanPostProcessor、
InstantiationAwareBeanPostProcessor、
SmartInstantiationAwareBeanPostProcessor、
MergedBeanDefinitionPostProcessor【internalPostProcessors】、

1)、获取所有的 BeanPostProcessor;后置处理器都默认可以通过PriorityOrdered、Ordered接口来执行优先级
2)、先注册PriorityOrdered优先级接口的BeanPostProcessor;
把每一个BeanPostProcessor;添加到BeanFactory中
beanFactory.addBeanPostProcessor(postProcessor);
3)、再注册Ordered接口的
4)、最后注册没有实现任何优先级接口的
5)、最终注册MergedBeanDefinitionPostProcessor;
6)、注册一个ApplicationListenerDetector;来在Bean创建完成后检查是否是ApplicationListener,如果是
applicationContext.addApplicationListener((ApplicationListener<?>) bean);
7、initMessageSource();初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
1)、获取BeanFactory
2)、看容器中是否有id为messageSource的,类型是MessageSource的组件
如果有赋值给messageSource,如果没有自己创建一个DelegatingMessageSource;
MessageSource:取出国际化配置文件中的某个key的值;能按照区域信息获取;
3)、把创建好的MessageSource注册在容器中,以后获取国际化配置文件的值的时候,可以自动注入MessageSource;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
MessageSource.getMessage(String code, Object[] args, String defaultMessage, Locale locale);
8、initApplicationEventMulticaster();初始化事件派发器;
1)、获取BeanFactory
2)、从BeanFactory中获取applicationEventMulticaster的ApplicationEventMulticaster;
3)、如果上一步没有配置;创建一个SimpleApplicationEventMulticaster
4)、将创建的ApplicationEventMulticaster添加到BeanFactory中,以后其他组件直接自动注入
9、onRefresh();留给子容器(子类)
1、子类重写这个方法,在容器刷新的时候可以自定义逻辑;
10、registerListeners();给容器中将所有项目里面的ApplicationListener注册进来;
1、从容器中拿到所有的ApplicationListener
2、将每个监听器添加到事件派发器中;
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
3、派发之前步骤产生的事件;
11、finishBeanFactoryInitialization(beanFactory);初始化所有剩下的单实例bean;
1、beanFactory.preInstantiateSingletons();初始化后剩下的单实例bean
1)、获取容器中的所有Bean,依次进行初始化和创建对象
2)、获取Bean的定义信息;RootBeanDefinition
3)、Bean不是抽象的,是单实例的,是懒加载;
1)、判断是否是FactoryBean;是否是实现FactoryBean接口的Bean;
2)、不是工厂Bean。利用getBean(beanName);创建对象
0、getBean(beanName); ioc.getBean();
1、doGetBean(name, null, null, false);
2、先获取缓存中保存的单实例Bean。如果能获取到说明这个Bean之前被创建过(所有创建过的单实例Bean都会被缓存起来)
从private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);获取的
3、缓存中获取不到,开始Bean的创建对象流程;
4、标记当前bean已经被创建
5、获取Bean的定义信息;
6、【获取当前Bean依赖的其他Bean;如果有按照getBean()把依赖的Bean先创建出来;】
7、启动单实例Bean的创建流程;
1)、createBean(beanName, mbd, args);
2)、Object bean = resolveBeforeInstantiation(beanName, mbdToUse);让BeanPostProcessor先拦截返回代理对象;
【InstantiationAwareBeanPostProcessor】:提前执行;
先触发:postProcessBeforeInstantiation();
如果有返回值:触发postProcessAfterInitialization();
3)、如果前面的InstantiationAwareBeanPostProcessor没有返回代理对象;调用4)
4)、Object beanInstance = doCreateBean(beanName, mbdToUse, args);创建Bean
1)、【创建Bean实例】;createBeanInstance(beanName, mbd, args);
利用工厂方法或者对象的构造器创建出Bean实例;
2)、applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
调用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition(mbd, beanType, beanName);
3)、【Bean属性赋值】populateBean(beanName, mbd, instanceWrapper);
赋值之前:
1)、拿到InstantiationAwareBeanPostProcessor后置处理器;
postProcessAfterInstantiation();
2)、拿到InstantiationAwareBeanPostProcessor后置处理器;
postProcessPropertyValues();
=====赋值之前:===
3)、应用Bean属性的值;为属性利用setter方法等进行赋值;
applyPropertyValues(beanName, mbd, bw, pvs);
4)、【Bean初始化】initializeBean(beanName, exposedObject, mbd);
1)、【执行Aware接口方法】invokeAwareMethods(beanName, bean);执行xxxAware接口的方法
BeanNameAware\BeanClassLoaderAware\BeanFactoryAware
2)、【执行后置处理器初始化之前】applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
BeanPostProcessor.postProcessBeforeInitialization();
3)、【执行初始化方法】invokeInitMethods(beanName, wrappedBean, mbd);
1)、是否是InitializingBean接口的实现;执行接口规定的初始化;
2)、是否自定义初始化方法;
4)、【执行后置处理器初始化之后】applyBeanPostProcessorsAfterInitialization
BeanPostProcessor.postProcessAfterInitialization();
5)、注册Bean的销毁方法;
5)、将创建的Bean添加到缓存中singletonObjects;
ioc容器就是这些Map;很多的Map里面保存了单实例Bean,环境信息。。。。;
所有Bean都利用getBean创建完成以后;
检查所有的Bean是否是SmartInitializingSingleton接口的;如果是;就执行afterSingletonsInstantiated();
12、finishRefresh();完成BeanFactory的初始化创建工作;IOC容器就创建完成;
1)、initLifecycleProcessor();初始化和生命周期有关的后置处理器;LifecycleProcessor
默认从容器中找是否有lifecycleProcessor的组件【LifecycleProcessor】;如果没有new DefaultLifecycleProcessor();
加入到容器;

写一个LifecycleProcessor的实现类,可以在BeanFactory
void onRefresh();
void onClose();
2)、 getLifecycleProcessor().onRefresh();
拿到前面定义的生命周期处理器(BeanFactory);回调onRefresh();
3)、publishEvent(new ContextRefreshedEvent(this));发布容器刷新完成事件;
4)、liveBeansView.registerApplicationContext(this);

=================================总结=================================
1)、Spring容器在启动的时候,先会保存所有注册进来的Bean的定义信息;
1)、xml注册bean;<bean>
2)、注解注册Bean;@Service、@Component、@Bean、xxx
2)、Spring容器会合适的时机创建这些Bean
1)、用到这个bean的时候;利用getBean创建bean;创建好以后保存在容器中;
2)、统一创建剩下所有的bean的时候;finishBeanFactoryInitialization();
3)、后置处理器;BeanPostProcessor
1)、每一个bean创建完成,都会使用各种后置处理器进行处理;来增强bean的功能;
AutowiredAnnotationBeanPostProcessor:处理自动注入
AnnotationAwareAspectJAutoProxyCreator:来做AOP功能;
xxx....
增强的功能注解:
AsyncAnnotationBeanPostProcessor
....
4)、事件驱动模型;
ApplicationListener;事件监听;
ApplicationEventMulticaster;事件派发:

Spring IOC创建

准备对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class IOCTest {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ioc.xml");
User user = applicationContext.getBean(User.class);
System.out.println(user);
}
}

@Data
public class User {
private String name;
private int age;

public User() {
this.name = "laowang";
this.age = 18;
System.out.println("======== user 实例创建 ========");
}
}

配置文件:

1
2
3
4
5
6
7
8
<?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 id="user" class="com.arsenal.ioc.User"/>

</beans>

org.springframework.context.support.AbstractApplicationContext#refresh方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
@Override
public void refresh() throws BeansException, IllegalStateException {
//同步锁,确保多线程情况下,IOC容器只被创建一次
synchronized (this.startupShutdownMonitor) {
//初始化配置准备刷新,验证环境中的一些必选参数
// Prepare this context for refreshing.
prepareRefresh();

//spring解析xml配置文件将要创建的所有bean的配置信息保存起来(点击进入该方法可以了解Spring对xml的解析,此时还没创建bean)
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

//初始化 beanFactory 的基本信息,包括 classLoader、environment、忽略的注解等。
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);

try {
//beanFactory的后置处理器
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
//处理beanFactory的后置处理器
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
//注册Spring自己的bean的后置处理器
// 执行 BeanFactoryPostProcessor(在beanFactory)初始化过程中,bean 初始化之前,修改BeanFactory 参数
// BeanDefinitionRegistryPostProcessor 其实也是继承自 BeanFactoryPostProcessor,
// 多个对 BeanDefinitionRegistry 的支持 invokeBeanFactoryPostProcessors(beanFactory)
// 执行 postProcess,那 BeanPoseProcessor 是什么呢,是为了在 bean 加载过程中修改 bean 的内容,
// 使用Before、After分别对应初始化前和初始化后
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
//支持国际化功能
// Initialize message source for this context.
initMessageSource();
// 初始化事件广播 ApplicationEventMulticaster,使用观察者模式,对注册的 ApplicationEvent
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
//空方法,专门留给子类的,实现自己逻辑的
// Initialize other special beans in specific context subclasses.
onRefresh();
//注解一些监听器
// 将所有 ApplicationEventListener 注册到 ApplicationEventMulticaster 中
// Check for listener beans and register them.
registerListeners();
//完成beanFactory的初始化(此时用户的单实例bean创建)下面进入该方法详细看用户单实例bean创建过程
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// 初始化 lifeCycle 的bean启动(例如 quartz 的定时器),如果开启 JMX 则将 ApplicationContext 注册到上面
// Last step: publish corresponding event.
finishRefresh();
}

catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已经创建单例
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// 将 context 的状态转换为无效,标示初始化失败
// Reset 'active' flag.
cancelRefresh(ex);

// Propagate exception to caller.
throw ex;
}

finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}

org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/**
* Finish the initialization of this context's bean factory,
* initializing all remaining singleton beans.
*/
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.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}

// 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();
//下面进入该方法详细看用户单实例bean创建过程
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}

org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons方法(用户的单实例bean创建)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}

//拿到所有要创建的bean名
// 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<>(this.beanDefinitionNames);

//按顺序创建bean
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
//根据bean的id拿到bean的定义信息
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//只创建非抽象,单例,非懒加载的bean
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//判断是否是工厂bean,我们自己的bean在下面else里
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
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());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
//该方法下创建我们自定义bean细节,后面调的是AbstractBeanFactory的doGetBean(name, null, null, false);(下面研究该方法)
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((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}

org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/**
* Return an instance, which may be shared or independent, of the specified bean.
* @param name the name of the bean to retrieve
* @param requiredType the required type of the bean to retrieve
* @param args arguments to use when creating a bean instance using explicit arguments
* (only applied when creating a new instance as opposed to retrieving an existing one)
* @param typeCheckOnly whether the instance is obtained for a type check,
* not for actual use
* @return an instance of the bean
* @throws BeansException if the bean could not be created
*/
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

final String beanName = transformedBeanName(name);
Object bean;

//先从已注册的所有单实例bean的缓存中找有没有注册过该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 (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else 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);
}
}

//检测该bean是否已创建,防止多线程情况下,重复创建
if (!typeCheckOnly) {
//标记该bean已创建
markBeanAsCreated(beanName);
}

try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);

//拿到创建当前bean之前需要提前创建的bean。depends-on属性:如果有就循环创建
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}

//创建bena实例
// Create bean instance.
if (mbd.isSingleton()) {
//具体创建bean实例方法,DefaultSingletonBeanRegistry下的getSingleton方法(下面仔细研究该方法)
sharedInstance = getSingleton(beanName, () -> {
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, () -> {
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 && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
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;
}

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/**
* Return the (raw) singleton object registered under the given name,
* creating and registering a new one if none registered yet.
* @param beanName the name of the bean
* @param singletonFactory the ObjectFactory to lazily create the singleton
* with, if necessary
* @return the registered singleton object
*/
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
//bean的实际创建(利用反射创建对象)
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
//在singletonObjects 这个Map中添加创建的bean,这个singletonObjects的Map保存保存单实例的bean。下面看该方法
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* Add the given singleton object to the singleton cache of this factory.
* <p>To be called for eager registration of singletons.
* @param beanName the name of the bean
* @param singletonObject the singleton object
*/
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#singletonObjects 这个Map保存所有单实例的bean对象

1
2
/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

DEBUG过程

org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization

org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization

org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons

org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton

基于xml的自定义IOC

项目结构

装配bean相关的类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package org.arsenal.xml.assemble;

/**
* @Author: Arsenal
* @Date: 2020-10-03 19:37
* @Description:
*/
public class BeanDefinition {
/**
* bean名称
*/
private String beanName;
/**
* bean的class对象
*/
private Class beanClass;
/**
* bean的class的包路径
*/
private String beanClassName;
/**
* bean依赖属性
*/
private PropertyValues propertyValues = new PropertyValues();


public String getBeanName() {
return beanName;
}

public void setBeanName(String beanName) {
this.beanName = beanName;
}

public Class getBeanClass() {
return beanClass;
}

public void setBeanClass(Class beanClass) {
this.beanClass = beanClass;
}

public String getBeanClassName() {
return beanClassName;
}

public void setBeanClassName(String beanClassName) {
this.beanClassName = beanClassName;
}

public PropertyValues getPropertyValues() {
return propertyValues;
}

public void setPropertyValues(PropertyValues propertyValues) {
this.propertyValues = propertyValues;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package org.arsenal.xml.assemble;

/**
* @Author: Arsenal
* @Date: 2020-10-03 19:43
* @Description:
*/
public class PropertyValue {

private final String name;
private final Object value;

public PropertyValue(String name, Object value) {
this.name = name;
this.value = value;
}

public String getName() {
return name;
}

public Object getValue() {
return value;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package org.arsenal.xml.assemble;

import java.util.LinkedList;
import java.util.List;

/**
* @Author: Arsenal
* @Date: 2020-10-03 19:43
* @Description:
*/
public class PropertyValues {

private List<PropertyValue> propertyValues = new LinkedList<>();

public List<PropertyValue> getPropertyValues() {
return propertyValues;
}

public void addPropertyValue(PropertyValue propertyValue) {
propertyValues.add(propertyValue);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package org.arsenal.xml.assemble;

/**
* @Author: Arsenal
* @Date: 2020-10-03 20:01
* @Description:
*/
public class BeanReference {

private String ref;

public BeanReference(String ref) {
this.ref = ref;
}

public String getRef() {
return ref;
}
}
1
2
3
4
5
6
7
8
9
10
11
package org.arsenal.xml.assemble;


/**
* @Author: Arsenal
* @Date: 2020-10-03 20:34
* @Description:
*/
public interface BeanDefinitionRegistry {
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition);
}
1
2
3
4
5
6
7
8
9
10
package org.arsenal.xml.assemble;

/**
* @Author: Arsenal
* @Date: 2020-10-03 20:34
* @Description:
*/
public interface BeanDefinitionReader {
void loadBeanDefinitions(String location) throws Exception;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package org.arsenal.xml.assemble;

import org.arsenal.xml.resource.ResourceLoader;
import org.springframework.util.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;

/**
* @Author: Arsenal
* @Date: 2020-10-03 20:35
* @Description:
*/
public class XmlBeanDefinitionReader implements BeanDefinitionReader {

/**
* BeanDefinition注册到BeanFactory接口
*/
private BeanDefinitionRegistry registry;
/**
* 资源载入类
*/
private ResourceLoader resourceLoader;

public BeanDefinitionRegistry getRegistry() {
return registry;
}

public ResourceLoader getResourceLoader() {
return resourceLoader;
}

public XmlBeanDefinitionReader(BeanDefinitionRegistry registry, ResourceLoader resourceLoader) {
this.registry = registry;
this.resourceLoader = resourceLoader;
}

@Override
public void loadBeanDefinitions(String location) throws Exception {
InputStream is = getResourceLoader().getResource(location).getInputStream();
doLoadBeanDefinitions(is);
}

private void doLoadBeanDefinitions(InputStream is) throws Exception {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse(is);
registerBeanDefinitions(document);
is.close();
}

private void registerBeanDefinitions(Document document) {
Element root = document.getDocumentElement();
parseBeanDefinitions(root);
}

private void parseBeanDefinitions(Element root) {
NodeList childNodes = root.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node node = childNodes.item(i);
if (node instanceof Element) {
Element element = (Element) node;
processBeanDefinition(element);
}
}
}

private void processBeanDefinition(Element element) {
String beanName = element.getAttribute("id");
String className = element.getAttribute("class");
if (beanName == null || className.length() == 0) {
throw new IllegalArgumentException("Configuration exception: <bean> element must has class attribute.");
}

if (StringUtils.isEmpty(beanName)) {
beanName = className;
}

BeanDefinition beanDefinition = new BeanDefinition();
beanDefinition.setBeanClassName(className);
processBeanProperty(element, beanDefinition);
getRegistry().registerBeanDefinition(beanName, beanDefinition);
}

private void processBeanProperty(Element element, BeanDefinition beanDefinition) {
NodeList propertyNodeList = element.getElementsByTagName("property");
for (int i = 0; i < propertyNodeList.getLength(); i++) {
Node node = propertyNodeList.item(i);
if (node instanceof Element) {
Element property = (Element) node;
String name = property.getAttribute("name");
String value = property.getAttribute("value");
if (StringUtils.hasText(value)) {
beanDefinition.getPropertyValues().addPropertyValue(new PropertyValue(name, value));
} else {
String ref = property.getAttribute("ref");
if (StringUtils.isEmpty(ref)) {
throw new IllegalArgumentException("Configuration problem: <property> element for " +
name + " must specify a value or ref.");
}
BeanReference reference = new BeanReference(ref);
beanDefinition.getPropertyValues().addPropertyValue(new PropertyValue(name, reference));
}
}
}
}
}

需自定义IOC容器管理的bean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package org.arsenal.xml.bean;

/**
* @Author: Arsenal
* @Date: 2020-10-08 16:55
* @Description:
*/
public class Car {

private String color;
private String brand;

public String getColor() {
return color;
}

public void setColor(String color) {
this.color = color;
}

public String getBrand() {
return brand;
}

public void setBrand(String brand) {
this.brand = brand;
}

@Override
public String toString() {
return "Car{" +
"color='" + color + '\'' +
", brand='" + brand + '\'' +
'}';
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package org.arsenal.xml.bean;

/**
* @Author: Arsenal
* @Date: 2020-10-08 16:54
* @Description:
*/
public class User {

private String username;
private Car car;

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public Car getCar() {
return car;
}

public void setCar(Car car) {
this.car = car;
}

@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", car=" + car +
'}';
}
}

context相关的类

1
2
3
4
5
6
7
8
9
10
11
package org.arsenal.xml.context;

import org.arsenal.xml.factory.BeanFactory;

/**
* @Author: Arsenal
* @Date: 2020-10-08 16:18
* @Description:
*/
public interface ApplicationContext extends BeanFactory {
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package org.arsenal.xml.context;

import org.arsenal.xml.assemble.BeanDefinitionRegistry;
import org.arsenal.xml.factory.ConfigurableListableBeanFactory;
import org.arsenal.xml.factory.DefaultListableBeanFactory;

/**
* @Author: Arsenal
* @Date: 2020-10-08 16:18
* @Description:
*/
public abstract class AbstractApplicationContext implements ApplicationContext {

private ConfigurableListableBeanFactory beanFactory;

@Override
public Object getBean(String beanName) {
return beanFactory.getBean(beanName);
}

public void refresh() throws Exception{
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
onRefresh();
}

protected void onRefresh() throws Exception {
beanFactory.preInstantiateSingletons();
}

protected abstract void loadBeanDefinitions(BeanDefinitionRegistry registry) throws Exception;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package org.arsenal.xml.context;


import org.arsenal.xml.assemble.BeanDefinitionRegistry;
import org.arsenal.xml.assemble.XmlBeanDefinitionReader;
import org.arsenal.xml.resource.ResourceLoader;

/**
* @Author: Arsenal
* @Date: 2020-10-08 16:31
* @Description:
*/
public class ClasspathXmlApplicationContext extends AbstractApplicationContext {

private String location;

public ClasspathXmlApplicationContext(String location) {
this.location = location;
try {
refresh();
} catch (Exception e) {
e.printStackTrace();
}
}

@Override
protected void loadBeanDefinitions(BeanDefinitionRegistry registry) throws Exception {
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(registry, new ResourceLoader());
reader.loadBeanDefinitions(location);
}
}

factory相关类:

1
2
3
4
5
6
7
8
9
10
package org.arsenal.xml.factory;

/**
* @Author: Arsenal
* @Date: 2020-10-08 16:19
* @Description:
*/
public interface BeanFactory {
Object getBean(String beanName);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package org.arsenal.xml.factory;

import org.arsenal.xml.assemble.BeanDefinition;
import org.arsenal.xml.assemble.BeanReference;
import org.arsenal.xml.assemble.PropertyValue;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
* @Author: Arsenal
* @Date: 2020-10-08 16:24
* @Description:
*/
public abstract class AbstractBeanFactory implements ConfigurableListableBeanFactory {

private Map<String, Object> singleObjects = new ConcurrentHashMap<>();

@Override
public Object getBean(String beanName) {
Object singleBean = this.singleObjects.get(beanName);
if (singleBean != null) {
return singleBean;
}

BeanDefinition beanDefinition = getBeanDefinitionByName(beanName);
if (beanDefinition == null) {
throw new RuntimeException("bean for name '" + beanName + "' not register.");
}

singleBean = doCreateBean(beanDefinition);
this.singleObjects.put(beanName, singleBean);
return singleBean;
}

protected abstract BeanDefinition getBeanDefinitionByName(String beanName);

protected Object doCreateBean(BeanDefinition beanDefinition) {
Object bean = createInstance(beanDefinition);
applyPropertyValues(bean, beanDefinition);
return bean;
}

protected Object createInstance(BeanDefinition beanDefinition) {
try {
if (beanDefinition.getBeanClass() != null) {
return beanDefinition.getBeanClass().newInstance();
} else if (beanDefinition.getBeanClassName() != null) {
try {
Class clazz = Class.forName(beanDefinition.getBeanClassName());
beanDefinition.setBeanClass(clazz);
return clazz.newInstance();
} catch (ClassNotFoundException e) {
throw new RuntimeException("bean Class " + beanDefinition.getBeanClassName() + " not found");
}
}
} catch (Exception e) {
throw new RuntimeException("create bean " + beanDefinition.getBeanName() + " failed");
}
throw new RuntimeException("bean name for " + beanDefinition.getBeanName() + " not define bean class");
}

protected void applyPropertyValues(Object bean, BeanDefinition beanDefinition) {
for (PropertyValue propertyValue : beanDefinition.getPropertyValues().getPropertyValues()) {
String name = propertyValue.getName();
Object value = propertyValue.getValue();
if (value instanceof BeanReference) {
BeanReference reference = (BeanReference) value;
value = getBean(reference.getRef());
}
try {
Method method = bean.getClass().getDeclaredMethod("set" + name.substring(0, 1).toUpperCase() +
name.substring(1), value.getClass());
method.setAccessible(true);
method.invoke(bean, value);
} catch (Exception e) {
try {
Field field = bean.getClass().getDeclaredField(name);
field.setAccessible(true);
field.set(bean, value);
} catch (Exception e1) {
throw new RuntimeException("inject bean property " + name + " failed");
}
}
}
}
}
1
2
3
4
5
6
7
8
9
10
package org.arsenal.xml.factory;

/**
* @Author: Arsenal
* @Date: 2020-10-08 16:21
* @Description:
*/
public interface ConfigurableListableBeanFactory extends BeanFactory {
void preInstantiateSingletons() throws Exception;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package org.arsenal.xml.factory;

import org.arsenal.xml.assemble.BeanDefinition;
import org.arsenal.xml.assemble.BeanDefinitionRegistry;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
* @Author: Arsenal
* @Date: 2020-10-08 16:23
* @Description:
*/
public class DefaultListableBeanFactory extends AbstractBeanFactory implements BeanDefinitionRegistry {

private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
private List<String> beanDefinitionNames = new LinkedList<>();

@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
beanDefinitionMap.put(beanName, beanDefinition);
beanDefinitionNames.add(beanName);
}

@Override
protected BeanDefinition getBeanDefinitionByName(String beanName) {
return beanDefinitionMap.get(beanName);
}

@Override
public void preInstantiateSingletons() throws Exception {
for (String beanName : beanDefinitionNames) {
getBean(beanName);
}
}

}

resource相关类

1
2
3
4
5
6
7
8
9
10
11
12
13
package org.arsenal.xml.resource;

import java.io.IOException;
import java.io.InputStream;

/**
* @Author: Arsenal
* @Date: 2020-10-03 20:02
* @Description:
*/
public interface Resource {
InputStream getInputStream() throws IOException;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package org.arsenal.xml.resource;

import java.io.IOException;
import java.io.InputStream;

/**
* @Author: Arsenal
* @Date: 2020-10-03 20:07
* @Description:
*/
public class ClassPathResource implements Resource {

private String path;

private ClassLoader classLoader;

public ClassPathResource(String path) {
this(path, null);
}

public ClassPathResource(String path, ClassLoader classLoader) {
this.path = path;
this.classLoader = classLoader == null ? Thread.currentThread().getContextClassLoader() : classLoader;
}

@Override
public InputStream getInputStream() throws IOException {
return classLoader.getResourceAsStream(path);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package org.arsenal.xml.resource;

/**
* @Author: Arsenal
* @Date: 2020-10-03 20:18
* @Description:
*/
public class ResourceLoader {

final String CLASSPATH_URL_PREFIX = "classpath:";

public Resource getResource(String location) {
if (location.startsWith(CLASSPATH_URL_PREFIX)) {
return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()));
} else {
return new ClassPathResource(location);
}
}

}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package org.arsenal.xml;

import org.arsenal.xml.bean.User;
import org.arsenal.xml.context.ApplicationContext;
import org.arsenal.xml.context.ClasspathXmlApplicationContext;


/**
* @Author: Arsenal
* @Date: 2020-10-03 19:36
* @Description:
*/
public class MyIoc {
public static void main(String[] args) {
ApplicationContext context = new ClasspathXmlApplicationContext("classpath:my-ioc.xml");
User user = (User) context.getBean("user");
System.out.println("user:" + user);
}
}

my-ioc.xml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
<beans>

<bean id="user" class="org.arsenal.xml.bean.User">
<property name="username" value="laowang"/>
<property name="car" ref="car"/>
</bean>

<bean id="car" class="org.arsenal.xml.bean.Car">
<property name="color" value="blue"/>
<property name="brand" value="Benz"/>
</bean>

</beans>

延伸

    Spring(ioc篇)
    Spring源码解析
    Spring源码解读
    雷丰阳_spring源码
    SpringIoc 实现原理
    Spring IOC原理总结
    深入理解 Spring IoC

Content
  1. 1. 前言
  2. 2. Spring IOC创建
  3. 3. DEBUG过程
  4. 4. 基于xml的自定义IOC
  5. 5. 延伸