前言
这部分开始,主要接触的就是spring体系结构的这部分内容:
这部分可以看成是IOC【Inversion of Control】。简单理解ioc就是对象由代码方式创建变成交给spring容器创建。
权威解释如下:
IOC是控制反转,而DI【依赖注入】是IOC的一种实现方式。这里的反转可能理解起来有点抽象,那么有反转自然应该有正转。什么是正转呢?我们可以按照传统的JavaSE思想,在A类里,写代码B b = new B();,通过new关键字获取A类的依赖对象,或者通过工厂模式进行获取,当然还有等等其它方法。这些方法,就属于正转的方法,因为A类获取B类就是通过主动的方法进行获取的,统称为正转的方法。既然正转是主动的方式,那么反转就是被动的方式。也即我们要获取某个类的依赖对象,不需要类主动去创建。交由Spring框架来给我们进行创建。这就是反转的意思了。在Spring框架里,实现IOC,是通过IOC容器实现的,由IOC容器负责创建和获取依赖对象,对象只是被动地接受依赖对象。
正转的弊端
上面已经说了,正转就是自己new一个对象出来供自己使用,自己new对象有什么弊端呢?如下图:
Spring-IOC反转的解耦
自己实现IOC控制反转
1. 引入依赖
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.11</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
2. 配置文件
<beans>
<bean id="userDao" clazz="com.mayuanfei.springioc.dao.impl.UserDaoImpl"/>
</beans>
3. Bean配置对象
public class Bean {
/**
* bean的id
*/
private String id;
/**
* bean的全路径名
*/
private String clazz;
}
4. Bean容器
public class BeanContext {
public Map<String, Object> beansMap = new ConcurrentHashMap<String, Object>();
/**
* 构造方法.把配置文件的类路径传入
*
* @param classPath 类路径文件名
*/
public BeanContext(String classPath) {
InputStream resource = BeanContext.class.getClassLoader().getResourceAsStream(classPath);
Document document = XmlUtil.readXML(resource);
List<Element> elements = XmlUtil.getElements(XmlUtil.getRootElement(document), "bean");
for (Element element : elements) {
beansMap.put(element.getAttribute("id"),
ReflectUtil.newInstance(element.getAttribute("clazz")));
}
}
/**
* 获得Bean实例对象
*
* @param id bean的id
* @return 实例对象
*/
public Object getBean(String id) {
if (beansMap.containsKey(id)) {
return beansMap.get(id);
}
return null;
}
}
5. UserDao接口
public interface UserDao {
/**
* 添加数据
*/
public void append();
}
6. UserDao两个实现类
public class UserDaoImpl implements UserDao {
/**
* 添加数据
*/
@Override
public void append() {
System.out.println("UserDaoImpl 插入数据库");
}
}
public class UserDaoImpl2 implements UserDao {
/**
* 添加数据
*/
@Override
public void append() {
System.out.println("UserDaoImpl2 插入数据库");
}
}
7. 测试类
@Test
public void testIoc() {
BeanContext context = new BeanContext("BeanConfig.xml");
UserDao userDao = (UserDao) context.getBean("userDao");
userDao.append();
}
8.代码地址
gitee.com/mayuanfei/S… 下的SpringIoc01
记忆印记
- 控制反转(IOC)是一个编程思想,而依赖注入(DI)是该思想的一个具体实现
- IOC理解为:以前自己new对象,现在交给spring框架帮忙管理创建对象,用的时候让spring框架帮忙注入即可
- IOC实现的核心为一个配置文件,一个维护id和实例对象的Map