Spring核心之IOC与DI:手写工厂到Spring容器演进(第一部分)
一、Spring框架简介Spring是一个轻量级的、开源的JavaEE全栈式应用框架。它的核心价值在于简化企业级应用开发通过提供一系列模块化解决方案让开发者能够更专注于业务逻辑。Spring的核心优势IOC控制反转将对象的创建、管理与依赖关系的控制权从程序代码“反转”到Spring容器实现解耦。AOP面向切面编程允许将遍布应用的公共行为如日志、事务从核心业务逻辑中分离增强模块化。粘合剂它就像一个“框架的框架”能够非常方便地整合MyBatis、Hibernate、Struts等其他优秀的第三方技术与框架。二、IOC控制反转从工厂模式到Spring容器2.1 问题起源耦合在传统编码中对象间的依赖关系通常是“硬编码”的。例如在Service层中直接new一个Dao层的实现类。这种强耦合导致代码僵化一旦需要更换实现就必须修改源代码。2.2 IOC思想正转程序员在代码中主动new对象控制权在程序员手中。反转IOC对象的创建不再由程序员控制而是交给一个“工厂”或“容器”来负责。程序员从主动创建变为被动接收对象。核心控制对象的创建权发生反转。2.3 手工实现IOC工厂模式在接触Spring前我们可以用“工厂反射配置文件”模拟IOC思想解耦Service和Dao。实现步骤定义配置文件 (bean.properties)将类名以键值对形式存储。userDaocom.hg.dao.UserDaoImpl userServicecom.hg.service.UserServiceImpl创建工厂类在静态代码块中读取配置文件。反射创建对象通过Class.forName(className).newInstance()创建对象实例并存入一个Map容器。提供获取方法对外提供getBean(String id)方法从Map中返回所需对象。此时Service中不再出现new UserDaoImpl()的代码而是从工厂获取初步实现解耦。2.4 Spring的IOC容器Spring将上述工厂模式的思想发挥到极致提供了一个功能强大的IOC容器。Spring IOC 入门步骤引入依赖 (pom.xml)dependency groupIdorg.springframework/groupId artifactIdspring-context/artifactId version5.3.23/version !-- 请使用合适版本 -- /dependency dependency groupIdorg.slf4j/groupId artifactIdslf4j-log4j12/artifactId version1.7.36/version /dependency准备日志配置 (log4j.properties)编写Spring配置文件 (applicationContext.xml)?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beans xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd !-- bean标签将一个类的对象交给Spring IOC容器管理 -- !-- id: 对象在容器中的唯一标识 (Map的key) -- !-- class: 对象的全限定类名 -- bean iduserDao classcom.hg.dao.UserDaoImpl/bean bean iduserService classcom.hg.service.UserServiceImpl/bean /beans从容器中获取Beanpublic class Test { public static void main(String[] args) { // 1. 加载Spring配置文件初始化IOC容器 ApplicationContext ac new ClassPathXmlApplicationContext(applicationContext.xml); // 2. 从容器中获取Bean对象 UserService userService ac.getBean(userService, UserService.class); // 3. 使用对象 userService.saveUser(); } }三、DI依赖注入IOC解决了对象创建的问题。DI依赖注入 则专门解决对象间的依赖关系赋值问题它是IOC思想的具体实现。3.1 构造方法注入通过类的构造方法来完成依赖的注入。目标类提供带参构造方法public class UserServiceImpl implements UserService { private UserDao userDao; private String msg; // 构造方法 public UserServiceImpl(UserDao userDao, String msg) { this.userDao userDao; this.msg msg; } }在配置文件中使用constructor-arg标签注入bean iduserService classcom.hg.service.UserServiceImpl !-- name: 通过构造方法参数名匹配 -- constructor-arg nameuserDao refuserDao/ !-- index: 通过构造方法参数索引位置匹配 (从0开始) -- constructor-arg index1 value示例文本/ /bean bean iduserDao classcom.hg.dao.UserDaoImpl/ref引用IOC容器中其他Bean的id。value注入基本数据类型或String类型的值。3.2 Setter方法注入最常用通过类的Setter方法来完成依赖注入。目标类提供Setter方法public class UserServiceImpl implements UserService { private UserDao userDao; private String msg; // Setter 方法 public void setUserDao(UserDao userDao) { this.userDao userDao; } public void setMsg(String msg) { this.msg msg; } }在配置文件中使用property标签注入bean iduserService classcom.hg.service.UserServiceImpl !-- name: 取set方法名去掉“set”后首字母小写的部分例如setUserDao - userDao -- property nameuserDao refuserDao/ property namemsg value示例文本/ /bean bean iduserDao classcom.hg.dao.UserDaoImpl/3.3 自动注入Autowire让Spring容器自动寻找匹配的Bean并完成注入无需在property或constructor-arg中显式配置。byType方式根据属性的类型在IOC容器中查找匹配的Bean。要求容器中同类型的Bean必须唯一。bean iduserService classcom.hg.service.UserServiceImpl autowirebyType/ bean iduserDao classcom.hg.dao.UserDaoImpl/ !-- 注意不能再有另一个类型为UserDao的bean否则会报错 --原理Spring会遍历IOC容器中所有的Bean检查其类型是否与UserServiceImpl中需要注入的属性如UserDao类型匹配如果找到且唯一则自动注入。总结IOC 是一种设计思想将对象的控制权交给容器实现解耦。DI 是IOC的一种实现方式由容器在运行时动态地将依赖关系注入到组件中。在Spring中IOC容器通过读取配置XML或注解来管理Bean及其依赖关系DI则负责建立Bean之间的关联。 从手写工厂到使用Spring容器我们看到了这一思想从概念到强大工业级实现的演进过程。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2409967.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!