Spring Framework之初识架构

一、前言

Spring Framework框架被人们亲切地称为 “ Spring ”,也就是春天的意思,柳暗花明又一村。
随着Spring的普及,越来越多的开发商加入了Spring的大家庭,Spring究竟为何物?这也需要我们更加全面地去了解,下面我通过以下5点带你们走入Spring的世界:
1.Spring Framework是什么?
2.什么是IOC、DI?
3.什么是AOP?
4.初步实现一个自己的IOC(依赖Spring Framework的核心原理)🌟
5.如何使用Spring Framework?

二、Spring Framework是什么

Spring Framework是由其IOC、DI和AOP为核心的开源项目。
现在已经成为每个公司所必备的底层项目之一,故现在的项目绝大部分都是Srping应用项目。
于 “ 2008-07-10 22:00 ”构建其开源仓库,但它研发的时间却更早。

以Rod Johnson和Juergen Hoeller两人为核心的一个开发团队经过努力,于2004年3月份发布了Spring Framework 1.0版 - 摘自百度百科

三、什么是IOC、DI

IOC ( Inversion Of Control ) 控制反转,指将对象创建的生命周期交给Spring Framework去进行管理、构建。
DI ( Dependency Injection ) 依赖注入,指对象间相互依赖的构建场景下,Spring Framework会自动进行其依赖对象的注入。

四、什么是AOP

AOP ( Aspect Oriented Programming ) 面向切面编程,通过预编译和运行期间动态代理的方式来实现程序统一维护的一种技术。
通过AOP对各业务进行隔离,使其耦合度降低,提高程序的可重用性,同时也提高了其开发效率。

五、初步实现一个自己的IOC(依赖Spring Framework的核心原理)🌟

完成了bean的基本构建、bean的懒加载功能及IOC基础的生命周期功能,接下来我们大概观看整个IOC容器的运行状态。

项目gitee地址:https://gitee.com/xusccn/my-ioc
此实现会让你最简单的了解Spring Framework的基本原理🌟

MainTest

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class MainTest {
static final Logger LOG = LoggerFactory.getLogger(MainTest.class);// 获取日志对象

@Test
public void ApplicationContextTest() {
// 1⃣️:构建应用上下文
ApplicationContext context = new ApplicationContext();
// 2⃣️:注册一个懒加载的User bean
context.registerBeanDefinition(User.class,true,true);
// 3⃣️:刷新应用上下文
context.refresh();
// 4⃣️:获取IOC容器bean对象
Object bean = context.getBean(User.class);
// 触发懒加载
LOG.info("{}",bean);
}
}

1⃣️:构建应用上下文

1
2
3
public ApplicationContext() {
this.beanFactory = new BeanFactory();
}

2⃣️:注册一个懒加载的User bean

1
2
3
4
5
6
7
8
9
10
11
12
13
// 通过类、懒加载属性、单例属性注入bean定义
public void registerBeanDefinition(Class clazz, boolean lazyInitialized, boolean single) {
beanFactory.registerBeanDefinition(clazz,lazyInitialized,single);
}

// 通过类、懒加载属性、单列属性注册bean定义
public void registerBeanDefinition(@NonNull Class clazz, boolean lazyInitialized, boolean single) {
BeanDefinition beanDefinition = new BeanDefinition(clazz, lazyInitialized, single);
beanDefinitionMap.put(beanDefinition.getClassName(),beanDefinition);
if (beanDefinition.isSingle() && !beanDefinition.isLazyInitialized()) {
singleBeanNameList.add(beanDefinition.getClassName());
}
}

3⃣️:刷新应用上下文

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
// 刷新上下文
public void refresh(){
synchronized (this.startupShutdownMonitor) {
// 1.准备刷新
prepareRefresh();

try {
// 2.实例化所有剩余的单列(未懒加载的)
finishBeanFactoryInitialization(beanFactory);

// 3.完成刷新
finishRefresh();
}catch (Exception e) {
// 销毁失败的beans
destroyBeans();

// 退出刷新
cancelRefresh();
throw e;
} finally {
// 4.重置通用缓存
resetCommonCaches();
}
}
}

4⃣️:获取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
59
60
61
62
63
64
65
66
67
68
69
// 通过类获取bean对象
public Object getBean(Class beanClass) {
return beanFactory.getBean(beanClass);
}

// 通过bean类获取bean对象
public Object getBean(@NonNull Class beanClass){
return getBean(beanClass.getName());
}

// 通过bean名获取bean对象
public Object getBean(String beanName){
BeanDefinition beanDefinition;
if ((beanDefinition = beanDefinitionMap.get(beanName)) == null) {
throw new IllegalStateException("beanName:[ " + beanName +" ] not register");
}
if (beanDefinition.isSingle()) {
return doGetSingleBean(beanName);⬅️
}
return initBean(beanName);
}

// 实际获取bean实现,由子类做具体实现
public abstract Object doGetSingleBean(String beanName);

// 最终获取bean对象的实现
@Override
public Object doGetSingleBean(String beanName) {
Object bean;
if ((bean = this.singletonObjects.get(beanName)) == null) {
//init bean
synchronized (singletonObjects) {
// DCL
if ((bean = this.singletonObjects.get(beanName)) == null) {
bean = initBean(beanName);⬅️
singletonObjects.put(beanName, bean);
}
}
}
return bean;
}

// 初始化bean
public Object initBean(String beanName){
Object bean = null;
BeanDefinition beanDefinition;
if ((beanDefinition = beanDefinitionMap.get(beanName)) == null) {
throw new IllegalStateException("beanName:[ " + beanName +" ] not register");
}

try {
if (beanDefinition.isLazyInitialized()) {
// lazy
bean = ProxyUtil.proxy(beanDefinition);
} else {
// promptly
bean = beanDefinition.getClazz().getDeclaredConstructor().newInstance();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return bean;
}

六、如何使用Spring Framework

依赖导入
gradle

1
testImplementation 'org.springframework:spring-context:5.3.5'

maven

1
2
3
4
5
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.5</version>
</dependency>

程序使用
步骤一(测试类):SpringFrameworkTest

1
2
3
4
5
6
7
8
9
10
11
public class SpringFrameworkTest {
private Logger log = LoggerFactory.getLogger(SpringFrameworkTest.class);

@Test
public void Test(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"spring.xml"},false);
context.refresh();
log.info("{}",context.getBean("systemPrint"));
log.info("{}",context.getBean("systemPrint"));
}
}

步骤二(配置文件):spring.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="systemPrint" class="SystemPrint">
<!-- collaborators and configuration for this bean go here -->
</bean>

<!-- more bean definitions go here -->

</beans>

步骤三(类对象):SystemPrint

1
2
3
public class SystemPrint {

}

程序执行输出

1
2
[Test worker] INFO SpringFrameworkTest - bean.SystemPrint@207fec97
[Test worker] INFO SpringFrameworkTest - bean.SystemPrint@207fec97
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

请我喝杯咖啡吧~

支付宝
微信