东营房地产网站建设,南昌网站建设维护,html怎么做网站后台,阿里巴巴集团控股有限公司SSM框架的学习与应用(Spring Spring MVC MyBatis)-Java EE企业级应用开发学习记录#xff08;第六天#xff09;初识Spring框架 昨天我们已经把Mybatis框架的基本知识全部学完#xff0c;内容有Mybatis是一个半自动化的持久层ORM框架#xff0c;深入学习编写动态SQL Spring MVC MyBatis)-Java EE企业级应用开发学习记录第六天初识Spring框架 昨天我们已经把Mybatis框架的基本知识全部学完内容有Mybatis是一个半自动化的持久层ORM框架深入学习编写动态SQLMybatis的关联映射一对一、一对多、多对多、Mybatis的缓存机制一二级缓存的开启和设置缓存命中率、如何使用idea链接数据库自动生成pojo类等。我们学习完了Mybatis今天是第六天那么我们要开始学习SSM框架的另外一个——Spring框架。 今天我们要掌握的是:
了解Spring框架及其优点了解Spring框架的体系结构与Spring 5的新特性*掌握Spring框架入门程序的编写理解控制反转的概念掌握依赖注入的概念、应用 一、Spring框架的基本概念
Spring致力于解决Java EE应用中的各种问题它是一个分层的Java SE/EE一站式full-stack开源的轻量级 Java 框架被广泛应用于企业级 Java 应用程序的开发中。它提供了一系列的模块用于解决常见的企业级应用开发问题包括依赖注入、AOP面向切面编程、声明式事务管理、Web 应用等等。
对于一个Java开发者来说Spring框架的熟练使用是必备的技能之一。Spring具有良好的设计和分层结构它克服了传统重量型框架臃肿、低效的劣势大大简化了项目开发中的技术复杂性。下面让我们来对Spring框架的基础知识进行详细的了解。 Spring框架的核心技术
它最为核心的理念是IoC控制反转和AOP面向切面编程其中IoC是Spring的基础它支撑着Spring对JavaBean的管理功能AOP是Spring 的重要特性AOP是通过预编译方式和运行期间动态代理实现程序功能也就是说可以在不修改源代码的情况下给程序统一添加功能。本文将带您探索 Spring 框架的强大功能与用途。 Spring 是一个综合性的框架可以在各个层次的应用程序中发挥作用 表现层Presentation Layer 在表现层Spring 提供了 Spring MVC 框架用于构建 Web 应用程序的控制器、视图解析、请求处理等。它支持处理用户请求、展示页面、接收表单数据等。Spring MVC 提供了通过注解或配置文件来定义控制器、请求映射、视图解析等的方式使得开发人员可以更方便地构建和维护 Web 页面。 业务逻辑层Business Logic Layer 在业务逻辑层Spring 提供了依赖注入DI和面向切面编程AOP等功能。这些功能可以帮助你更好地管理组件之间的关系实现松耦合的设计提高代码可测试性和可维护性。Spring 的 DI 让你可以通过配置或注解将组件的依赖关系交由 Spring 容器管理从而实现了对象的解耦和可替换性。AOP 允许我们在不改变原有代码的情况下通过切面将横切关注点如日志记录、事务管理与业务逻辑分离。 持久层Persistence Layer 在持久层Spring 提供了对多种持久化技术的支持包括 JDBC、JPA、Hibernate 等。Spring 的 JDBC 框架简化了数据库访问的操作提供了模板类JdbcTemplate和声明式事务管理等功能使数据库操作更方便和可靠。Spring 还可以集成其他 ORM 框架如 Mybatis、Hibernate 和 JPA使得数据持久化更加灵活和高效。
简单来说的话就是Spring 提供了一套综合性的工具和框架可以在不同层次的应用程序中分别发挥作用从而帮助开发人员构建更易于维护、可扩展和高效的应用。 Spring框架的优点
a.非侵入式设计
Spring是一种非侵入式non-invasive框架所谓非侵入式是指Spring框架的API不会在业务逻辑上出现也就是说业务逻辑应该是纯净的不能出现与业务逻辑无关的代码。由于业务逻辑中没有Spring的API所以业务逻辑代码也可以从Spring框架快速地移植到其他框架。
b.降低耦合性
Spring就是一个大工厂可以将所有对象的创建和依赖关系的维护工作都交给Spring容器管理大大降低了组件之间的耦合性。
c.支持AOP编程
Spring提供了对AOP的支持AOP可以将一些通用的任务进行集中处理如安全、事务和日志等以减少通过传统OOP方法带来的代码冗余和繁杂。
d.支持声明式事务
在Spring中可以直接通过Spring配置文件管理数据库事务省去了手动编程的繁琐提高了开发效率。
e.方便程序的测试
Spring提供了对Junit的支持开发人员可以通过Junit进行单元测试。
f.方便集成框架
Spring提供了一个广阔的基础平台其内部提供了对各种框架的直接支持如Struts、Hibernate、MyBatis、Quartz等这些优秀框架可以与Spring无缝集成。
g.降低Java EE API的使用难度
Spring对Java EE开发中的一些API如JDBC、JavaMail等都进行了封装大大降低了这些API的使用难度。 Spring的体系结构 Spring 5框架组成模块
Spring 框架主要有8大模块每个大模块由多个或1个小模块组成如Spring的核心容器模块Core Container是由Beans模块、Core模块、Context模块和SpEL模块组成。下面结合String 的体系结构图对Spring体系结构中的主要模块进行简单介绍。
a.核心容器模块Core Container
核心容器模块在Spring的功能体系中起着支撑性作用是其他模块的基石。核心容器层主要由Beans模块、Core模块、Contex模块和SpEL模块组成。
核心容器模块各模块组成
1Beans模块。它提供了BeanFactory类是工厂模式的经典实现Beans模块的主要作用是创建和管理Bean对象。
2Core模块。它提供了Spring框架的基本组成部分包括IoC和DI功能。
3Context模块。它构建于Beans模块和Core模块的基础之上它可以通过ApplicationContext接口提供上下文信息。
4SpEL模块。它是Spring 3.0后新增的模块提供了对SpEL表达式语言Spring Expression Language的支持SpEL表达式语言是一个在程序运行时支持操作对象图的表达式语言。 b.数据访问及集成模块Data Access/Integration
数据访问及集成模块用于访问和操作数据库中的数据它主要包含JDBC模块、ORM模块、OXM模块、JMS模块和Transactions模块。
1 JDBC模块。它提供了一个JDBC的抽象层消除了冗长的JDBC编码并能够解析数据库供应商特有的错误代码。
2ORM模块。它为主流的对象关系映射API提供了集成层用于集成主流的对象关系映射框架。 3OXM模块。它提供了对XML映射的抽象层的支持如JAXB、Castor等。
4JMS模块。它主要用于传递消息包含消息的生产和消费。自4.1版本后JMS模块支持与Spring-message模块的集成。
5Transactions模块。它的主要功能是事务管理。 c.Web模块
Web模块的实现基于APPlicationContext基础之上它提供了Web应用的各种工具类包括了Web模块、Servlet模块、WebSocket模块和Portlet模块。
1 Web模块。它提供了针对Web开发的集成特性如大部分文件上传功能等。此外Web模块还包含一个HTTP客户端和Spring远程处理支持的Web相关部分。
2Servlet模块。它提供了Spring的模型、视图、控制器以及Web应用程序的REST Web服务实现。
3WebSocket模块。它是Spring 4.0以后新增的模块它提供了WebSocket 和SockJS的实现以及对STOMP的支持。
4Portlet模块。它类似Servlet模块的功能提供了Portlet环境下的MVC实现。 d.其他模块
Spring框架的其他模块还有AOP模块、Aspects模块、Instrumentation模块以及Test模
1 AOP模块。它提供了对面向切面编程的支持程序可以定义方法拦截器和切入点将代码按照功能进行分离以降低程序的耦合性。
2Aspects模块。它提供了与AspectJ集成的支持。
3Instrumentation模块。它提供了对类工具的支持并且实现了类加载器该模块可以在特定的应用服务器中使用。
4Messaging模块。它是Spring 4.0以后新增的模块它提供了对消息传递体系结构和协议的支持。
5Test模块。它提供了对程序单元测试和集成测试的支持。
Spring 5是Spring当前最新的版本与历史版本对比Spring 5对Spring核心框架进行了修订和更新增加了很多新特性如支持响应式编程等。 Spring 5新特性
a.更新JDK基线
因为Spring 5代码库运行于JDK 8之上所以Spring 5对JDK的最低要求是JDK 8这可以促进Spring的使用者积极运用Java 8新特性。
b.修订核心框架
1基于JDK 8的反射增强通过Spring 5提供的方法可以更加高效的对类或类的参数进行访问。
2核心的Spring接口提供了基于JDK 8的默认方法构建的选择性声明。
3用Nullable和NotNull注解来表明可为空的参数以及返回值可以在编译时处理空值而不是在运行时抛出NullPointerExceptions异常。
c.更新核心容器
Spring 5支持候选组件索引作为类路径扫描的替代方案。从索引读取实体类会使加载组件索引开销更低因此Spring程序的启动时间将会缩减。
d.支持响应式编程
响应式编程是另外一种编程风格它专注于构建对事件做出响应的应用程序。Spring 5包含响应流和ReactorReactiveStream的Java实现响应流和Reactor支撑了Spring自身的功能及相关API。
e.支持函数式Web框架
Spring 5提供了一个函数式Web框架。该框架使用函数式编程风格来定义端点它引入了两个基本组件: HandlerFunction和RouterFunction。HandlerFunction 表示处理接收到的请求并生成响应函数RouterFunction替代了RequestMapping注解用于将接收到的请求转发到处理函数。
f.支持Kotlin
Spring 5提供了对Kotlin语言的支持。Kotlin是一种支持函数式编程风格的面向对象语言它运行在JVM之上可以让代码更具有表现力、简洁性和可读性。有了对Kotlin的支持开发人员可以进行深度的函数式Spring编程这拓宽了Spring的应用领域。
g.提升测试功能
Spring 5完全支持Junit 5 Jupiter因此可以使用Junit 5编写测试代码。除此之外Spring 5还提供了在Spring TestContext Framework中进行并行测试的扩展。针对响应式编程模型Spring 5引入了支持Spring webFlux的WebTestClient集成测试。 接触到Spring了基本就要开始综合项目的开发了那么我们首先要了解一下设计模式
什么是设计模式
设计模式软件模式是将模式的一般概念应用于软件开发领域即软件开发的总体指导思路或参照样板。软件模式并非仅限于设计模式还包括架构模式、分析模式和过程模式等实际上在软件生存期的每一个阶段都存在着一些被认同的模式。
目前主流的设计模式有三种分类
一按创建型模式分类 简单工厂模式( Simple Factory Pattern ) 工厂方法模式(Factory Method Pattern) 抽象工厂模式(Abstract Factory) 建造者模式 单例模式
二按结构型模式分类 适配器模式 桥接模式 装饰模式 外观模式 享元模式 代理模式
三按行为型模式分类 命令模式 中介者模式 观察者模式 状态模式 策略模式
这些后续会一篇一篇发出来会一直更新的这里就优先讲一下简单工厂模式吧。 一、用一个例子来说明接口、简单工厂模式、控制反转IOC
步骤1、接口的创建实现和实例化对象练习
Java接口是一系列方法的声明是一些方法特征的集合一个接口只有方法的特征没有方法的实现因此这些方法可以在不同的地方被不同的类实现而这些实现可以具有不同的行为功能。
接口可以理解为一种特殊的类里面全部是由全局常量和公共的抽象方法所组成。接口是解决Java无法使用多继承的一种手段。
Java接口和抽象类的区别:简单来说 接口是公开的里面不能有私有的方法或变量jdk8后可以有私有方法和静态常量jdk9以后可以有私有的变量这里的环境是jdk8所以其他不讲是用于让别人使用的而抽象类是可以有私有方法或私有变量的另外实现接口的一定要实现接口里定义的所有方法而实现抽象类可以有选择地重写需要用到的方法。 一般的应用里最顶级的是接口然后是抽象类实现接口最后才到具体类实现。 还有接口可以实现多重继承而一个类只能继承一个超类但可以通过继承多个接口实现多重继承接口还有标识里面没有任何方法如Remote接口和数据共享里面的变量全是常量的作用.
①创建任意项目后创建simpleFactory包后包内创建名字为Fruit的接口 ②用同样的方法创建俩个实现了Fruit的类Apple和Banana
Apple.class
public class Apple implements Fruit {public void show() {System.out.println(采集苹果); }
}Banana.class
public class Banana implements Fruit {public void show() {System.out.println(采集香蕉); }}③实例化对象a.若使用传统方法不采用工厂模式我们实例化苹果和香蕉的方法如下
package simpleFactory;public class MainClass {public static void main(String[] args) {//不用工厂模式的实例化类的方法Apple a1new Apple(); //实例化一个苹果对象Banana b1new Banana(); //实例化一个香蕉对象a1.show();//输出苹果对象的show方法b1.show ();//输出香蕉对象的show方法}
}
④实例化对象b.使用简单工厂模式实例化Apple和Banana,我们需要先创建一个工厂类名为FruitFactory.java,代码如下
package simpleFactory;public class FruitFactory {public static Fruit getFruit(String type) {Fruit fruitFactory null; //先定义一个水果对象(没确定是苹果或香蕉)if(type.equals(Apple)){fruitFactory new Apple();//创建苹果对象}else if(type.equals(Banana)){fruitFactory new Banana();//创建香蕉对象}return fruitFactory;//返回对应的水果}}这段代码的话其实跟我们前面几天的封装自己的工具类是差不多的就是封装通过统一的方法根据接受的参数不同然后来生成对应类型的对象。
public class MainClass {public static void main(String[] args) {//工厂模式的方法;Fruit a1 FruitFactory.getFruit(Apple);Fruit b1 FruitFactory.getFruit(Banana);a1.show();//输出苹果对象的show方法 b1.show();//输出香蕉对象的show方法}
}输出结果
⑤c.实例化拓展使用反射创建实例这样的话我们得对FruitFactory类的代码进行修改
什么是反射
反射是一种在运行时检查、检测和操作类、接口、字段、方法等程序结构的能力。它允许程序在运行时获取关于类的信息并操作类或对象的属性、方法和构造函数而无需在编译时硬编码这些信息。
Java中的反射机制允许我们
获取类的信息可以在运行时获取类的名称、父类、实现的接口、字段、方法等信息。创建对象通过反射可以实例化对象就像使用 new 关键字一样。调用方法通过反射可以调用对象的方法包括私有方法。访问和修改字段可以访问和修改对象的字段包括私有字段。操作构造函数可以通过反射调用类的构造函数来实例化对象。
反射机制在某些情况下非常有用例如在框架、库、插件和动态加载类等场景中。但需要注意由于反射涉及到在运行时进行检查和操作可能会影响性能并且由于绕过了编译时的类型检查可能导致运行时的类型错误。 修改代码如下 public class FruitFactory {public static Fruit getFruit(String type) {/*这里通过反射的方式获取到水果子类的字节码即类对象通过类对象的newInstance()方法创建水果子类*/Class fruit Class.forName(FruitFactory.class.getPackage().getName().type);return (Fruit) fruit.newInstance();}}这里FruitFactory.class.getPackage().getName()是用来找到FruitFactory所在的包你也可以直接写上你水果类所在的包的名称如simpleFactory.type
然后鼠标移到所有有波浪线的代码上点add.exception.to…
如下图 再回到主类MainClass的主函数Main中鼠标移到波浪线上右击添加add.throw.declaration
(注意这里将工厂类和所创建的子类放在同一个包simFactory中方便调用。)
上面通过反射的方式获取到水果子类的字节码即类对象通过类对象的newInstance()方法创建水果子类。
保存运行后结果虽然不变但是这里采用了反射的方法不需要去判断有多少种水果分别写上代码但是这里要加上throw的预出错处理防止用户写错类名无法创建出对应的类。 上面的简单工厂模型实现了控制反转的概念即创建类的对象由Apple,Banana转移到了FruitFactory这个工厂类上。 二、下面我们学习使用Spring的搭建和并使用它实现控制反转创建对象
Spring的作用简单介绍一下
1、Spring 的主要作用就是为代码“解耦”降低代码间的耦合度。在一个软件系统中根据功能的不同代码可以分成两大类主业务逻辑和系统级业务逻辑。它们各自具有鲜明的特点
主业务代码间逻辑联系紧密有具体的专业业务应用场景复用性相对较低系统级业务相对功能独立没有具体的专业业务应用场景主要是为主业务提供系统级服务如用户、权限管理日志记录、安全管理、事务管理等复用性强。
2、Spring 根据代码的功能特点将降低耦合度的方式分为了两类IOC 与AOP。
IoC 使得主业务在相互调用过程中不用再自己维护关系了即不用再自己创建要使用的对象了。而是由 Spring 容器统一管理自动“注入”。而 AOP 使得系统级服务得到了最大复用且不用再由程序员手工将系统级服务“混杂”到主业务逻辑中了而是由 Spring 容器统一完成“注入”。 搭建Spring环境
①往刚刚新建的项目里面修改pom
写上需要的依赖文件代码如下
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdorg.example/groupIdartifactIdspringIocTest/artifactIdversion1.0-SNAPSHOT/versiondependenciesdependencygroupIdorg.mybatis/groupIdartifactIdmybatis/artifactIdversion3.5.2/version/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.11/version/dependencydependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.12/versionscopecompile/scope/dependencydependencygroupIdlog4j/groupIdartifactIdlog4j/artifactIdversion1.2.17/version/dependency!--Spring的基础包Spring-core--dependencygroupIdorg.springframework/groupIdartifactIdspring-core/artifactIdversion5.2.8.RELEASE/version/dependency!--Spring的基础包Spring-beans--dependencygroupIdorg.springframework/groupIdartifactIdspring-beans/artifactIdversion5.2.8.RELEASE/version/dependency!--Spring的基础包Spring-context--dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion5.2.8.RELEASE/version/dependency!--Spring的基础包Spring-expressinon--dependencygroupIdorg.springframework/groupIdartifactIdspring-expression/artifactIdversion5.2.8.RELEASE/version/dependency!--Spring的依赖包commons-logging--dependencygroupIdcommons-logging/groupIdartifactIdcommons-logging/artifactIdversion1.2/version/dependency/dependenciesbuildresourcesresourcedirectorysrc/main/java/directoryincludesinclude**/*.properties/includeinclude**/*.xml/include/includesfilteringtrue/filtering/resource/resources/build
/project然后点开右边的maven窗口点刷新等依赖文件下载完成 若是下载失败可以自行导入本地离线包我的项目资料文件资源文件里面有。
②创建entiy包定义一个Person类
package entity;public class Person {private String name;private int age;public void show() {System.out.println(name:name,age:age);}public String getName() {return name;}public void setName(String name) {this.name name;}public int getAge() {return age;}public void setAge(int age) {this.age age;}
}
③创建spring-config.xml文件或者直接复制我项目资源里面的
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.2.xsdbean idperson classentity.Personproperty namename value张三/propertyproperty nameage value24/property/bean
/beans④创建Test包进行测试类编写
package Test;import entity.Person;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class PersonTest{Testpublic void test1() {ApplicationContext context new ClassPathXmlApplicationContext(spring-config.xml);Person person context.getBean(person, Person.class);person.show();}
}输出结果如下 你会发现这里的值跟我们在spring-config.xml中配置的bean一样。 这里我们并没有手动创建Person的实例对象是Spring通过ApplicationContext帮我们创建并放在IoC容器里。ApplicationContext是一个IoC容器接口它所创建的对象都称作是bean也就是xml文件里的bean id class /bean这行配置信息。getBean方法就是从IoC容器里取得这个对象根据标识id 和类名class然后我们就可以调用该类的方法如下图 接下来尝试使用Spring框架来实现我们一开始的Fruit类
①在entity包下创建接口Fruit并且接口中定义一个show()
package entity;public interface Fruit {public void show();
}和前面的文章一样在Fruit处使用Altenter创建出接口的实现类Apple和Banana
Apple.java代码如下并且定义了一个int类型的weight变量
package entity;public class Apple implements Fruit {private int weight;Overridepublic void show() {System.out.println(采集苹果:weight斤);}public int getWeight() {return weight;}public void setWeight(int weight) {this.weight weight;}
}
Banana.java代码如下并且也定义了一个int类型的weight变量
package entity;public class Banana implements Fruit {private int weight;public int getWeight() {return weight;}public void setWeight(int weight) {this.weight weight;}Overridepublic void show() {System.out.println(采集香蕉:weight斤);}
}②往spring-config.xml中添加上Apple和Banana类 ③编写测试类FruitTest
package Test;import entity.Apple;
import entity.Banana;
import entity.Fruit;
import javafx.application.Application;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import static org.junit.jupiter.api.Assertions.*;class FruitTest {Testvoid getFruitWeight() {ApplicationContext context new ClassPathXmlApplicationContext(spring-config.xml);Fruit applecontext.getBean(apple, Apple.class);Fruit Bananacontext.getBean(banana, entity.Banana.class);apple.show();Banana.show();}
}可以看出简单工厂模式和我们使用Spring框架的效果其实是一样的简单地说Spring模型的核心思想就是把创建对象的工作交给Spring去做在spring-config.xml中配置好要创建的对象然后在实际代码用用context.getBean()函数创建出对象 (相对应于简单工厂模式用工厂类去创建对象)。
实现了控制的反转IOC即将创建对象的控制权转发生了转变。 Spring的依赖注入
对象的组装依赖注入练习,并了解“面向接口编程”的含义。
下面我们用一个例子来说明“依赖注入”这个概念。
说明“依赖”指的是在一个类中如果包含另一个类如
Class A;
Class B{A aa;…
}
Class C{B b;…
}上面的B类中包含着A类可以看成A类是B类的一个字段这就表示B类“依赖”A类。在实例化B类之前需要先实例化A类。
这种就是类和类之间的依赖关系。
传统的面向对象编程类和类之间的依赖过于复杂。B依赖AC又依赖BD又依赖C在创建对象D的时候需要依次对前面的类进行实例化相当麻烦使用了Ioc之后类之间的依赖关系就变得简单明了请看下面我们用一个打印机的例子来说明使用Ioc之后依赖关系的解决方法这种方法就称为“依赖注入” 需求如下
开发一个打印机模拟程序使其符合以下条件。
可以灵活地配置使用彩色墨盒或灰色墨盒。可以灵活地配置打印页面的大小。程序中包括打印机Printer、墨盒Ink和纸张Paper三类组件如下所示 打印机依赖墨盒和纸张。
采取如下的步骤开发这个程序。
1定义Ink和Paper接口。
2使用Ink接口和Paper接口开发Printer程序。在开发Printer程序
时并不依赖Ink和Paper的具体实现类。
3开发Ink接口和Paper接口的实现类Color Ink、Grey Ink和
Text Paper。
4组装打印机运行调试。 ①创建printer包在包内定义Ink和Paper接口
记得命名要符合驼峰命名这样方便代码让别人读懂自己也写的比较规范利于团队协作
Ink接口
package printer;public interface Ink {public String getColor();//判断什么颜色型号的打印机
}Paper接口
package printer;public interface Paper {public String getPaperType();//判断打印的纸张是什么纸型的
}②创建Printer类用来接收参数并且打印的类记得这个不用继承接口
package printer;public class Printer {//面向接口编程而不是具体的实现类private Ink inknull;//面向接口编程而不是具体的实现类private Paper papernull;public void print(String str){//输出标记颜色System.out.println(使用ink.getColor()打印\n);//输出纸型System.out.println(使用paper.getPaperType()打印\n);//输出字符串System.out.println(str);}//生成getter和setter方法public Ink getInk() {return ink;}public void setInk(Ink ink) {this.ink ink;}public Paper getPaper() {return paper;}public void setPaper(Paper paper) {this.paper paper;}
}
说明Printer类中只有一个print()方法输入参数是一个即将被打印的字符串打印机将这个字符串逐个字符输出到纸张然后将纸张中的内容输出。
在开发Printer程序的时候只需要了解Ink接口和Paper接口即可完全不需要依赖这些接口的某个具体实现类这是符合实际情况的。在设计真实的打印机时也是这样设计师只是针对纸张和墨盒的接口规范进行设计。
在使用时只要符合相应的规范打印机就可以根据需要更换不同的墨盒和纸张。
软件设计与此类似由于明确地定义了接口在编写代码的时候完全不用考虑和某个具体实现类的依赖关系从而可以构建更复杂的系统。组件间的依赖关系和接口的重要性在将各个组件组装在一起的时候得以体现。通过这种开发模式还可以根据需要方便地更换接口的实现就像为打印机更换不同的墨盒和纸张一样。Spring提倡面向接口编程也是基于这样的考虑。
注意Ink和Paper只是接口不是类是不能创建实例的print()方法运行的时候是从哪里获得Ink和Paper的实例呢这时就需要提供“插槽”以便组装的时候可以将Ink和Paper的实例“注入”进来下面我们实义Ink和Paper对应的实现类以便用它们生成实例。 ③创建Ink的俩个实现类BlackWhiteInk和ColorInk分别代表黑白打印机和彩色打印机
这里因为类比较少我就直接在printer包下创建了因为我是几个实例一起写的创建太多包容易搞混当然了如果是有经验的那么就还是按照各个分类包来编写实现类和接口。BlackWhiteInk.java
package printer;public class BlackWhiteInk implements Ink {Overridepublic String getColor() {String color黑白打印机;return color;}
}ColorInk.java
package printer;public class ColorInk implements Ink {Overridepublic String getColor() {String color彩色打印机;return color;}
}③创建Paper的实现类PaperType里面创建变量用来接收纸型的信息。
上面的俩个实例都是指定好的了因为只有这俩种打印。纸型有很多种A3、A4、A5等
package printer;public class PaperType implements Paper {private String paper;//纸型Overridepublic String getPaperType() {return paper;}public String getPaper() {return paper;}public void setPaper(String paper) {this.paper paper;}
}
//说明在我们不仅可以注入某个类的实例还可以注入基本数据类型、字符串等类型的数据。④在 spring-config.xml 配置文件中注册实体类并使用控制反转IoC容器来实例化和组装打印机对象
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.2.xsdbean idperson classentity.Personproperty namename value张三/propertyproperty nameage value24/property/beanbean idapple classentity.Appleproperty nameweight value3/property/beanbean idbanana classentity.Bananaproperty nameweight value5/property/bean!-- 定义彩色墨盒bean该bean的id是colorInkclass指定该bean实例的实现类 --bean idcolorInk classprinter.ColorInk/bean!-- 定义灰色墨盒bean(也就是黑白打印机)该bean的id是blackWhiteInkclass指定该bean实例的实现类 --bean idblackWhiteInk classprinter.BlackWhiteInk/bean!-- 定义A4纸张bean该bean的id是a4Paperclass指定该bean实例的实现类 --bean ida4Paper classprinter.PaperTypeproperty namepaper valueA4paper/property/bean!-- 定义5纸张bean该bean的id是a5Paperclass指定该bean实例的实现类 --bean ida5Paper classprinter.PaperTypeproperty namepaper valueA5paper/property/bean!-- 组装打印机。定义打印机bean该bean的id是printer class指定该bean实例的实现类 --bean idprinter classprinter.Printer!-- 通过ref属性注入已经定义好的bean --!-- 注入彩色墨盒 --property nameink refcolorInk/!-- 注入A4打印纸张 --property namepaper refa4Paper//bean
/beans 我们实例化了前面的各个类并给里面的变量赋了值最后“组装”了一台彩色的、使用a4打印纸的打印机。需要注意的是这里没有使用property的value属性而是使用了ref属性。
value属性用于注入基本数据类型以及字符串类型的值。ref属性用于注入已经定义好的Bean如刚刚定义好的colorInk、blackWhiteInk、a4Paper和a5Paper。 ⑤编写测试类进行测试 若是想要更换打印机的配置也就是组装新的打印机可以回去spring-config.xml中修改bean中的配置又或者可以新建一个新的bean组装新的打印机。 和Spring有关的只有组装和运行两部分代码。仅这两部分代码就让我们获得了像更换打印机的墨盒和打印纸一样更换程序组件的能力。这就是Spring依赖注入的魔力。
通过Spring的强大组装能力我们在开发每个程序组件的时候只要明确关联组件的接口定义而不需要关心具体实现这就是所谓的“面向接口编程”。
以上的操作类和类之间的依赖关系通过Ioc在xml之中可以很清晰地表示出来很容易实现类和类之间的组装这种做法我们称为“依赖注入”英文简写为DI希望通过这个例子能够帮助各位慢慢消化理解这个概念。 总结
今天是学习SSM框架的第六天主题是初识Spring框架因为后面我们要开发综合项目了所以今天先学习了简单的设计模式**-简单工厂模式以及三种方式创建实例。然后了解了Spring框架是一个分层的Java SE/EE一站式full-stack开源的轻量级** Java 框架。基本熟悉了Spring框架的核心IoC和AoP的基本概念还学了IoC控制反转和DI依赖注入,以及这种方式创建的优点。Spring框架的熟练使用是必备的技能之一十分重要熟练的掌握它们能够极大的提高开发效率。
想要跟着学习的可以去我的资源里面找对应的文件下载我的md文件也会发上去项目文件会上传可以自己跟着学习一下。
作者Stevedash
发表于2023年8月30日 17点34分
注本文内容基于个人学习理解如有错误或疏漏欢迎指正。感谢阅读如果觉得有帮助请点赞和分享。