Spring学习2-对spring解耦机制的理解

解耦

个人理解,spring首先创建一个bean.xml的配置文件,创建一个核心容器,然后根据配置文件中bean的id来创建对象,通过这种方式来实现解耦,这和通过工厂模式创建一个bean.propertie配置文件,然后创建map容器存放bean对象是同一种思想:

工厂模式

1
2
ACCOUNTSERVICE=com.gsynf.service.impl.AccountServiceImpl
ACCOUNTDAO=com.gsynf.dao.impl.AccountDaoImpl
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
package com.gsynf.factory;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;

import com.gsynf.service.IAccountService;

/**
* @ClassName: BeanFactory
* @Description: 用于创建Bean对象的工厂
* Bean:在我们工程中,就可以看成是一些对象
* @author: gsynf
* @date: 2019年10月26日 下午5:20:18
*/
public class BeanFactory {
// 1.它可以用来读取properties文件;
// 2.它只能用于读取,不能用于写入;
// 3.它只能读取类路径下的,不在类路径下的不能都读取;
private static ResourceBundle bundle = ResourceBundle.getBundle("config.bean"); //参数指的是properties文件的位置,写法是包名.类名,不要写扩展名

// 定义一个容器,用于存放所有的bean对象
private static Map<String, Object> beans = new HashMap<String, Object>();

// 使用静态代码块,给容器填充内容
static {
try {
// 1.读取所有的key
Enumeration<String> keys =bundle.getKeys();
// 2.遍历所有的key
while(keys.hasMoreElements()) {
//取出key
String key = keys.nextElement();
//根据key获取value
String beanPath = bundle.getString(key);
//反射创建bean对象
Object value = Class.forName(beanPath).newInstance();
//把创建出来的对象和key存入map中
beans.put(key, value);
}
} catch (Exception e) {
throw new ExceptionInInitializerError("初始化容器失败!");
}
}

/**
* @Title: getBean
* @Description: 用于创建bean对象的方法
* @param beanName 容器中bean的key
* @return 对应的bean对象
* @return: Object
*/
public static Object getBean(String beanName) {
return beans.get(beanName);
}
}

spring

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
<?xml version="1.0" encoding="UTF-8"?>
<!-- 导入spring的约束
spring的IOC约束:beans
-->
<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标签:
作用:用于让spring帮我们读取配置后创建对象
属性:
id:对象的唯一标识
class:要创建的对象的全限定类名
-->
<bean id="accountService" class="com.gsynf.service.impl.AccountServiceImpl"></bean>

<!-- 配置持久层对象
创建的反射对象存在哪里了呢?core container
-->
<bean id="accountDao" class="com.gsynf.dao.impl.AccountDaoImpl"></bean>


</beans>
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
package com.gsynf.ui;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.gsynf.dao.IAccountDao;
import com.gsynf.service.IAccountService;
import com.gsynf.service.impl.AccountServiceImpl;

/**
* @ClassName: Client
* @Description: 模拟一个表现层
* @author: gsynf
* @date: 2019年10月26日 下午5:14:43
*/

public class Client {

/**
* @Title: main
* @Description: 获取spring的核心容器,并且根据bean的id获取对象
* @param args
* @return: void
*/
public static void main(String[] args) {
// 1.获取spring的核心容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
// 2.根据bean的id获取对象
IAccountService as = (IAccountService) ac.getBean("accountService");
IAccountDao adao = ac.getBean("accountDao", IAccountDao.class);

System.out.println(as);
System.out.println(adao);
}
}

另:获取spring核心容器详解

1
2
3
4
5
6
7
8
9
10
11
ApplicationContext:BeanFactory子接口的子接口,较为常用
特点:创建bean对象时,采用立即加载的策略。(当读取完xml配置文件,配置文件中所有的bean对象都已经创建完成)
使用场景:对象只创建一次,例如单例对象
BeanFactory:springIoc容器的顶层接口
特点:创建bean对象时,采用延迟加载的策略。(当真正要从容器中获取bean对象时才创建,读取完xml配置文件并不创建)
使用场景:对象创建多次,例如多例对象

ClassPathXmlApplicationContext:
它是通过读取类路径下的配置文件创建spring容器,要求配置文件必须在类路径下。
FileSystemXmlApplicationContext:
它是通过读取文件系统中的配置文件创建spring容器,要求配置文件必须在文件系统中。

控制反转 Inversion of Control

原来:

​ 我们在获取对象时,都是采用new的方式。是主动的。

​ 现在:

​ 我们获取对象时,同时跟工厂要,有工厂为我们查找或者创建对象。是被动的。

​ 这种被动接收的方式获取对象的思想就是控制反转,它是spring框架的核心之一。

​ 它的作用只有一个:削减计算机程序的耦合。

:转载文章请注明出处,谢谢~