尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Spring框架核心(上)——IoC控制反转与DI依赖注入详解

Spring框架核心(上)——IoC控制反转与DI依赖注入详解 前言Spring框架自2003年兴起以来已成为Java企业级开发的事实标准。它由Rod Johnson在其著作《Expert One-On-One J2EE Development and Design》中阐述的理念衍生而来解决了企业应用开发的复杂性。本系列分为上下两篇上篇聚焦于Spring最核心的控制反转IoC和依赖注入DI涵盖XML配置、注解开发以及纯注解方式并配有大量实战代码。一、Spring框架概述1.1 什么是SpringSpring是一个开放源代码的设计层面框架它解决的是业务逻辑层和其他各层的松耦合问题将面向接口的编程思想贯穿整个系统。Spring是一个轻量级、一站式JavaSE/EE full-stack的开源框架。1.2 Spring的核心架构Spring的核心是IoC控制反转和AOP面向切面编程构建了一个分层架构允许开发者按需选择组件。┌─────────────────────────────────────────┐ │ 表现层Web层 │ ├─────────────────────────────────────────┤ │ 业务层Service层 │ ├─────────────────────────────────────────┤ │ 持久层DAO层 │ ├─────────────────────────────────────────┤ │ Spring核心容器IoC/AOP │ └─────────────────────────────────────────┘下图展示了Spring框架的经典分层架构IoC和AOP作为底层基石向上支撑着数据访问、Web层和业务逻辑层。1.3 Spring的主要优点解耦简化开发Spring作为大工厂管理对象创建和依赖关系。AOP编程支持方便实现权限拦截、运行监控等。声明式事务通过配置管理事务无需手动编码。方便测试与JUnit整合轻松测试。集成优秀框架支持Struts2、Hibernate、MyBatis等。降低API难度对JDBC、JavaMail等提供封装。二、IoC控制反转核心技术2.1 什么是IoCIoCInversion of Control即控制反转将对象的创建权力反转给Spring框架。它是一种设计原则用于降低代码之间的耦合度。传统方式UserService service new UserServiceImpl();主动创建IoC方式由Spring工厂创建对象我们被动获取。2.2 IoC快速入门步骤1创建Maven工程导入依赖xml dependencies dependency groupIdorg.springframework/groupId artifactIdspring-context/artifactId version5.0.2.RELEASE/version /dependency dependency groupIdcommons-logging/groupId artifactIdcommons-logging/artifactId version1.2/version /dependency dependency groupIdlog4j/groupId artifactIdlog4j/artifactId version1.2.12/version /dependency dependency groupIdjunit/groupId artifactIdjunit/artifactId version4.12/version scopetest/scope /dependency /dependencies步骤2编写接口与实现类java // UserService.java package com.example.service; public interface UserService { void hello(); } // UserServiceImpl.java package com.example.service; public class UserServiceImpl implements UserService { Override public void hello() { System.out.println(Hello IOC!!); } }步骤3编写Spring配置文件applicationContext.xmlxml ?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 iduserService classcom.example.service.UserServiceImpl/ /beans步骤4测试java Test public void testIoC() { ApplicationContext context new ClassPathXmlApplicationContext(applicationContext.xml); UserService service (UserService) context.getBean(userService); service.hello(); // 输出 Hello IOC!! }IoC容器获取Bean的流程如下图所示2.3 ApplicationContext工厂接口ClassPathXmlApplicationContext加载类路径下的配置文件。FileSystemXmlApplicationContext加载磁盘路径下的配置文件。2.4 Bean管理的XML配置属性说明idBean的唯一标识命名规范class类的全路径scope作用范围singleton默认单例、prototype多例、request、sessioninit-method/destroy-method生命周期回调方法示例xml bean iduserService classcom.example.service.UserServiceImpl scopesingleton init-methodinit destroy-methoddestroy/2.5 实例化Bean的三种方式2.5.1 默认无参构造最常用xml bean idus classcom.example.service.UserServiceImpl/2.5.2 静态工厂方法java public class StaticFactory { public static UserService createUs() { return new UserServiceImpl(); } } xml bean idus classcom.example.StaticFactory factory-methodcreateUs/2.5.3 实例工厂方法java public class DFactory { public UserService createUs() { return new UserServiceImpl(); } } xml bean iddfactory classcom.example.DFactory/ bean idus factory-beandfactory factory-methodcreateUs/三、DI依赖注入3.1 什么是DIDIDependency Injection即依赖注入在Spring创建Bean时动态地将依赖对象注入到Bean中。IoC是思想DI是实现方式。3.2 Setter方法注入java public class OrderServiceImpl implements OrderService { private OrderDao orderDao; private String msg; private int age; // 必须提供setter方法 public void setOrderDao(OrderDao orderDao) { this.orderDao orderDao; } public void setMsg(String msg) { this.msg msg; } public void setAge(int age) { this.age age; } // 业务方法... } xml bean idorderService classcom.example.OrderServiceImpl property nameorderDao reforderDao/ property namemsg value测试消息/ property nameage value18/ /bean3.3 构造方法注入java public class Car { private String cname; private Double money; public Car(String cname, Double money) { this.cname cname; this.money money; } } xml bean idcar classcom.example.Car constructor-arg namecname value奔驰/ constructor-arg namemoney value400000/ /bean3.4 集合类型注入支持数组、List、Set、Map、Properties等。xml bean idcollectionBean classcom.example.CollectionBean property namestrs arrayvalue美美/valuevalue小凤/value/array /property property namelist listvalue熊大/valuevalue熊二/value/list /property property namemap mapentry keyaaa value老王//map /property property nameproperties propsprop keyusernameroot/prop/props /property /bean三种注入方式关系图四、多配置文件加载方式一在主配置文件中导入xmlimport resourceapplicationContext2.xml/方式二工厂同时加载多个javaApplicationContext ac new ClassPathXmlApplicationContext(app1.xml, app2.xml);五、Spring整合JDBC实战IoCDI综合案例5.1 数据库准备sql CREATE DATABASE spring_db; USE spring_db; CREATE TABLE account ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(40), money DOUBLE ); INSERT INTO account VALUES (NULL,aaa,1000),(NULL,bbb,1000);5.2 依赖添加Druid和MySQL驱动xml dependency groupIdcom.alibaba/groupId artifactIddruid/artifactId version1.1.10/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version5.1.6/version /dependency5.3 实体类、DAO、Service代码省略getter/setterAccount.javajava public class Account { private Integer id; private String name; private Double money; // 构造、getter、setter、toString }AccountDao接口与实现java public interface AccountDao { ListAccount findAll(); } public class AccountDaoImpl implements AccountDao { private DataSource dataSource; public void setDataSource(DataSource dataSource) { this.dataSource dataSource; } Override public ListAccount findAll() { // 使用dataSource获取连接执行查询封装返回 // 代码略详见PDF } }AccountService接口与实现java public interface AccountService { ListAccount findAll(); } public class AccountServiceImpl implements AccountService { private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) { this.accountDao accountDao; } Override public ListAccount findAll() { return accountDao.findAll(); } }5.4 配置文件整合所有xml bean iddataSource classcom.alibaba.druid.pool.DruidDataSource property namedriverClassName valuecom.mysql.jdbc.Driver/ property nameurl valuejdbc:mysql:///spring_db/ property nameusername valueroot/ property namepassword valueroot/ /bean bean idaccountDao classcom.example.dao.AccountDaoImpl property namedataSource refdataSource/ /bean bean idaccountService classcom.example.service.AccountServiceImpl property nameaccountDao refaccountDao/ /bean5.5 测试java Test public void testFindAll() { ApplicationContext ac new ClassPathXmlApplicationContext(applicationContext.xml); AccountService service ac.getBean(AccountService.class); ListAccount list service.findAll(); list.forEach(System.out::println); }六、IOC注解方式6.1 快速入门在类上添加Component或Service、Repository、Controller并在配置文件中开启注解扫描。java Component(us) public class UserServiceImpl implements UserService { public void hello() { System.out.println(Hello IOC注解...); } } xml context:component-scan base-packagecom.example/测试时直接通过id获取。6.2 常用注解详解注解作用Component普通类标记为BeanController表现层Service业务层Repository持久层Value注入基本类型值Autowired按类型自动装配Qualifier与Autowired配合按名称注入ResourceJSR-250按名称注入Scope作用范围PostConstruct初始化方法PreDestroy销毁方法示例java Service Scope(singleton) public class Car { Value(大奔) private String cname; Autowired private Person person; PostConstruct public void init() { System.out.println(初始化); } }6.3 纯注解方式无XML配置类java Configuration ComponentScan(com.example) Import(OtherConfig.class) public class SpringConfig { Bean public DataSource dataSource() { DruidDataSource ds new DruidDataSource(); ds.setDriverClassName(com.mysql.jdbc.Driver); ds.setUrl(jdbc:mysql:///spring_db); ds.setUsername(root); ds.setPassword(root); return ds; } }测试java ApplicationContext ac new AnnotationConfigApplicationContext(SpringConfig.class); Order order ac.getBean(Order.class);七、Spring整合JUnit单元测试7.1 配置文件方式java RunWith(SpringJUnit4ClassRunner.class) ContextConfiguration(classpath:applicationContext.xml) public class TestDemo { Autowired private UserService userService; Test public void test() { userService.hello(); } }7.2 纯注解方式java RunWith(SpringJUnit4ClassRunner.class) ContextConfiguration(classes SpringConfig.class) public class TestDemo { Autowired private UserService userService; Test public void test() { userService.hello(); } }总结本篇详细介绍了Spring框架的IoC控制反转和DI依赖注入从XML配置到注解再到纯注解并通过整合JDBC的实战案例加深理解。掌握了这些内容您就打下了Spring的坚实基础。下篇我们将深入AOP面向切面编程、事务管理和JDBC模板等高级特性敬请期待。
返回列表