Java:面向对象 Spring 框架

Java:面向对象  Spring 框架 第一章 Spring 框架介绍1.1 框架概述Spring 是2003 年由 Rod Johnson 推出的开源、轻量级 Java 一站式full-stack框架理念来源于其著作《Expert One-On-One J2EE Development and Design》专为解决企业级应用开发复杂度而生。核心特点分层架构模块化设计开发者可按需选用组件无缝整合 JavaEE 各类技术。核心思想贯穿面向接口编程实现层与层之间松耦合。两大核心机制IOC控制反转将对象创建、管理工作交给 Spring 容器不再手动new对象。AOP面向切面编程在不修改原有源代码的前提下对方法进行功能增强日志、权限、监控等。1.2 Spring 框架优点解耦简化开发依托 IOC 容器统一管理所有对象与依赖关系彻底降低代码耦合度。支持 AOP 编程便捷实现权限拦截、运行监控、日志记录等通用功能。声明式事务通过配置即可完成事务管理无需手动编写事务代码。测试便捷完美兼容 JUnit4借助注解快速完成单元测试。框架兼容性强原生支持整合 Struts2、Hibernate、MyBatis 等主流开源框架。简化 JavaEE API对 JDBC、JavaMail 等复杂原生 API 进行封装大幅降低使用难度。第二章 Spring HelloWorld 入门案例2.1 环境准备Maven 导入依赖创建 Maven 工程在pom.xml中引入 Spring 核心、日志、单元测试依赖dependencies !-- Spring核心容器 -- 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 /dependencies2.2 编写业务 Demo 类package com.qcby.service; public class Demo { public void hello() { System.out.println(hello world); } }2.3 编写 Spring XML 配置文件在resources目录下创建applicationContext.xmlSpring 标准配置文件名使用bean标签交由 IOC 容器管理对象?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beans xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocation http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd !-- idBean唯一标识用于容器中获取对象 class类的全限定类名包名类名 -- bean iddemo classcom.qcby.service.Demo / /beans2.4 编写测试代码对比传统创建对象和Spring 容器获取对象两种方式package com.qcby.service; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class UserServiceTest { // 传统方式手动new对象耦合度高 Test public void run(){ Demo demo new Demo(); demo.hello(); } // Spring方式从IOC容器获取对象 Test public void run1(){ // 1. 加载配置文件初始化Spring容器 ApplicationContext ac new ClassPathXmlApplicationContext(applicationContext.xml); // 2. 根据id获取容器中的Bean对象 Demo demo (Demo) ac.getBean(demo); // 3. 调用方法 demo.hello(); } }第三章 Spring IOC 容器3.1 IOC 思想概述全称Inverse of Control控制反转。核心将对象创建、依赖管理的控制权从开发者代码中转移给 Spring IOC 容器。解决问题消除代码之间硬依赖大幅降低程序耦合度。传统开发中A 类主动newB 类层级依赖复杂时一处出错整体瘫痪使用 IOC 后所有对象统一由容器创建业务代码仅需调用容器对象解除硬绑定。3.2 IOC 容器底层三大核心技术DOM4J解析 XML 配置文件读取bean标签信息工厂模式统一工厂生产对象解耦调用方与目标类Java 反射运行时根据全类名动态创建对象。简易模拟 IOC 工厂public class DemoFactory { public static Demo getDemo() throws Exception { // 1. DOM4J解析XML拿到类全路径 String classPath com.qcby.service.Demo; // 2. 反射创建对象 Class? clazz Class.forName(classPath); return (Demo) clazz.newInstance(); } }3.3 IOC 容器两大实现类Spring IOC 容器管理的对象统称为Bean容器有两个核心接口BeanFactorySpring 底层原生接口框架内部使用不推荐开发者直接使用加载策略懒加载加载配置文件时不创建对象调用getBean()时才实例化。ApplicationContextBeanFactory的子接口功能更强大开发首选加载策略立即加载容器初始化时就创建所有单例 Bean额外拓展支持国际化、事件发布等功能。第四章 Bean 的作用域通过bean标签的scope属性配置 Bean 作用域Spring 5 共提供 6 种常用两种singleton默认单例作用域整个 IOC 容器中仅存在一个 Bean 实例容器初始化时创建对象全局共享。bean iddemo classcom.qcby.service.Demo scopesingleton/prototype多例作用域每次调用getBean()都会创建全新对象容器启动时不创建对象获取时才实例化。bean iddemo classcom.qcby.service.Demo scopeprototype/第五章 Spring Bean 管理5.1 Bean 管理概念Bean 管理包含两大核心操作创建类的实例对象为对象的成员属性依赖注入DI。5.2 Bean 管理两种方式基于XML 配置文件传统方式基于注解主流开发方式。5.3 基于 XML 的 Bean 管理5.3.1 XML 创建对象默认通过无参构造方法实例化类必须提供无参构造否则容器创建失败。bean iddemo classcom.qcby.service.Demo/5.3.2 XML 依赖注入DIDIDependency Injection依赖注入Spring 自动为对象属性赋值分为Set 注入、构造器注入。1Set 方式注入最常用要求属性必须提供setXxx()方法。① 普通属性 对象属性注入实体类package com.qcby.service; public class User { private int age; private String name; private Demo demo; // 引用类型 // 必须提供set方法 public void setAge(int age) { this.age age; } public void setName(String name) { this.name name; } public void setDemo(Demo demo) { this.demo demo; } Override public String toString() { return User{age age , name name , demo demo }; } }XML 配置value给基本类型 / 字符串赋值ref引用容器中其他 Bean 的 id。bean iddemo classcom.qcby.service.Demo/ bean iduser classcom.qcby.service.User property nameage value18/ property namename value张三/ property namedemo refdemo/ /bean测试代码Test public void testUser(){ ApplicationContext ac new ClassPathXmlApplicationContext(applicationContext.xml); User user ac.getBean(user, User.class); System.out.println(user); }② 数组、List、Map 集合注入实体类import java.util.List; import java.util.Map; public class CollectionBean { private String[] strs; private ListString list; private MapString,String map; public void setStrs(String[] strs) { this.strs strs; } public void setList(ListString list) { this.list list; } public void setMap(MapString, String map) { this.map map; } Override public String toString() { return CollectionBean{strs java.util.Arrays.toString(strs) , list list , map map }; } }XML 配置bean idcollectionBean classcom.qcby.service.CollectionBean !-- 数组 -- property namestrs array value美美/value value小凤/value /array /property !-- List集合 -- property namelist list value熊大/value value熊二/value /list /property !-- Map集合 -- property namemap map entry keyaaa value老王/ entry keybbb value小王/ /map /property /bean2构造器方式注入要求类提供有参构造方法使用constructor-arg标签赋值。 实体类public class Car { private String cname; private Double money; // 有参构造 public Car(String cname,Double money){ this.cname cname; this.money money; } Override public String toString() { return Car{cname cname , money money }; } }XML 配置bean idcar classcom.qcby.service.Car constructor-arg namecname value奔驰/ constructor-arg namemoney value35/ /bean5.4 基于注解的 Bean 管理注解作用简化 XML 配置是现代开发主流方式。5.4.1 实例化 Bean 四大注解四个注解功能完全一致仅用于分层区分Component通用普通组件Controller标注控制层类Service标注业务层类Repository标注数据访问层类。规则不指定名称时Bean id 默认是类名首字母小写可通过注解名(value自定义id)指定名称。5.4.2 注解开发步骤业务类添加注解package com.qcby.testanno; import org.springframework.stereotype.Controller; Controller(valueus) public class UserServiceImpl implements UserService { Override public void hello() { System.out.println(使用注解方便吧); } }XML 开启注解包扫描?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beans xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:contexthttp://www.springframework.org/schema/context xsi:schemaLocation http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd !-- 扫描指定包下所有带注解的类 -- context:component-scan base-packagecom.qcby/ /beans测试获取 BeanTest public void run1(){ ClassPathXmlApplicationContext ac new ClassPathXmlApplicationContext(applicationContext.xml); UserService us (UserService) ac.getBean(us); us.hello(); }5.4.3 注解实现属性注入Value注入普通类型、字符串Autowired按类型自动装配引用类型Qualifier配合Autowired按名称装配不可单独使用ResourceJDK 原生注解默认按名称注入。示例代码import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.annotation.Resource; Component(value c) public class Car { Value(大奔2) private String cname; Value(400000) private Double money; // 按类型注入 Autowired // 按名称注入搭配使用 // Qualifier(value person) // JDK注解 按名称注入 // Resource(name person) private Person person; Override public String toString() { return Car{cname cname , money money , person person }; } } Component class Person { Value(张三) private String pname; Override public String toString() { return Person{pname pname }; } }5.5 纯注解开发无 XML微服务主流方案使用配置类完全替代 XML 文件。核心注解Configuration标识当前类为 Spring 配置类ComponentScan开启包扫描。实现步骤实体类添加组件注解import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; Component public class Order { Value(北京) private String address; Override public String toString() { return Order{address address }; } }编写 Spring 配置类import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; Configuration // 声明配置类 ComponentScan(value com.qcby) // 包扫描 public class SpringConfig { }测试使用AnnotationConfigApplicationContext加载配置类import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Demo4 { Test public void run(){ // 加载配置类初始化容器 ApplicationContext ac new AnnotationConfigApplicationContext(SpringConfig.class); Order order (Order) ac.getBean(order); System.out.println(order); } }第六章 Bean 的生命周期6.1 完整生命周期 8 大阶段实例化IOC 容器通过无参构造创建 Bean 对象属性注入调用set方法完成属性赋值初始化前置处理Bean 后置处理器postProcessBeforeInitialization初始化执行自定义初始化方法初始化后置处理Bean 后置处理器postProcessAfterInitialization就绪可用Bean 正式交付业务使用销毁容器关闭时执行自定义销毁方法容器关闭。6.2 生命周期回调三种方式用于指定 Bean 初始化、销毁时执行的方法优先级注解 接口 XML。方式 1实现接口耦合度高不推荐实现InitializingBean初始化、DisposableBean销毁接口import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; public class Dog implements InitializingBean, DisposableBean { private String name; public Dog() { System.out.println(Dog 对象被创建); } public void setName(String name) { this.name name; } // 初始化方法 Override public void afterPropertiesSet() throws Exception { System.out.println(接口初始化方法执行); } // 销毁方法 Override public void destroy() throws Exception { System.out.println(接口销毁方法执行); } }方式 2XML 配置指定方法在bean标签中配置init-method初始化、destroy-method销毁bean iddog classcom.qcby.Dog init-methodinit destroy-methoddestroyFun/方式 3注解方式推荐使用PostConstruct初始化、PreDestroy销毁。6.3 Bean 后置处理器作用对容器中所有 Bean 生效在初始化前后统一拦截处理实现BeanPostProcessor接口。示例import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; public class MyBeanProcessor implements BeanPostProcessor { // 初始化之前执行 Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println(初始化前 beanName); return bean; } // 初始化之后执行 Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println(初始化后 beanName); return bean; } }XML 配置将后置处理器交由容器管理即可全局生效bean idmyBeanProcessor classcom.gs.process.MyBeanProcessor/补充依赖Lombok项目常用简化代码工具Maven 依赖dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId version1.18.12/version scopeprovided/scope /dependency