当前位置: 首页 > news >正文

Spring 概述

Spring 概述

在实际企业应用中,绝大部分企业架构都基于Spring框架。它最核心的理念是IoC(控制反转)和AOP(面向切面编程),其中IoC是Spring的基础,而AOP则是其重要的功能,最为典型的当属数据库事务的使用。

Spring历史

Rod Johnson在2002年编著的《Expert one on one J2EE design and development》一书中,对Java EE 系统框架臃肿、低效、脱离现实的种种现状提出了质疑,并积极寻求探索革新之道。以此书为指导思想,他编写了interface21框架,这是一个力图冲破J2EE传统开发的困境,从实际需求出发,着眼于轻便、灵巧,易于开发、测试和部署的轻量级开发框架。Spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵,于2004年3月24日,发布了1.0正式版。同年他又推出了一部堪称经典的力作《Expert one-on-one J2EE Development without EJB》,该书在Java世界掀起了轩然大波,不断改变着Java开发者程序设计和开发的思考方式。在该书中,作者根据自己多年丰富的实践经验,对EJB的各种笨重臃肿的结构进行了逐一的分析和否定,并分别以简洁实用的方式替换之。至此一战功成,Rod Johnson成为一个改变Java世界的大师级人物。

传统J2EE应用的开发效率低,应用服务器厂商对各种技术的支持并没有真正统一,导致J2EE的应用没有真正实现Write Once及Run Anywhere的承诺。Spring作为开源的中间件,独立于各种应用服务器,甚至无须应用服务器的支持,也能提供应用服务器的功能,如声明式事务、事务处理等。

Spring致力于J2EE应用的各层的解决方案,而不是仅仅专注于某一层的方案。可以说Spring是企业应用开发的“一站式”选择,并贯穿表现层、业务层及持久层。然而,Spring并不想取代那些已有的框架,而是与它们无缝地整合。

Spring特点(策略)

  • 轻量:对于POJO的潜力开发,提供轻量级和低侵入的编程,可以通过配置(xml、注解等)来扩展POJO的功能,通过依赖注入的理念去扩展功能;通过接口编程,强调OOD的开发模式理念,降低系统的耦合度,提高系统的可读性和可扩展性。
  • 面向切面:Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。使得开发人员把精力更加集中于业务开发而非技术本身,也避免了try-catch-finally的滥用。

Spring不排斥各种优秀的开源框架,相反,Spring可以降低各种框架的使用难度,Spring提供了模板类来整合各种优秀框架。

Spring IoC概述

2004年,Martin Fowler探讨了同一个问题,既然IoC是控制反转,那么到底是“哪些方面的控制被反转了呢?经过详细地分析和论证后,他得出了答案:“获得依赖对象的过程被反转了”。控制被反转之后,获得依赖对象的过程由自身管理变为了由IOC容器主动注入。于是,他给“控制反转”取了一个更合适的名字叫做“依赖注入(Dependency Injection)”。他的这个答案,实际上给出了实现IOC的方法:注入。所谓依赖注入,就是由IoC容器在运行期间,动态地将某种依赖关系注入到对象之中。

所以,依赖注入(DI)和控制反转(IoC)是从不同的角度的描述的同一件事情,就是指通过引入IoC容器,利用依赖关系注入的方式,实现对象之间的解耦。

在Spring中,实现控制反转的是IoC容器,其实现方法是依赖注入。Spring会提供IoC容器来管理对应的资源。

控制反转是一个比较抽象的概念,对于初学者不好理解,我们举例说明。

案例 组装电脑

每台电脑由内存、主板、CPU三个基本的电脑元件组成,内存及CPU需要插在主板上才能工作。我们假定有各式各样的主板、内存及CPU可供选择,因此可通过Java接口来抽象各配件的定义。

image

package com.computer.component;/*** 电脑组件接口* @author Jing61*/
public interface PCComponent {String getName(); // 获取组件名称double getPrice(); // 获取组件价格String getCompany(); // 获取组件厂家
}
package com.computer.component;/*** CPU接口* @author Jing61*/
public interface CPU extends PCComponent {int getSpeed(); // 获取CPU速度void doInstr(); // 做指令运算void outResult(); // 输出结果
}
package com.computer.component; /*** 内存接口* @author Jing61*/
public interface Ram extends PCComponent {int getSize(); // 获取内存大小void inData(); // 读数据void outData(); // 取数据
}
package com.computer.component;/*** 主板接口* @author Jing61*/
public interface Mainboard extends PCComponent {void setCpu(CPU cpu);//安装cpuCPU getCpu();//得到主板上的CPUvoid setRam(Ram ram);//安装内存Ram getRam();//得到主板上的内存boolean havePower();//是否有电源void startPower();//开电源void shutdownPower();//关电源
}

Computer类的设计及实现

每台Computer需要一个主板,每个主板上需要插上CPU及内存条,电脑才能正常工作。

image

package com.computer.computer;import com.computer.component.Mainboard;/*** 电脑类* @author Jing61*/
public class Computer {private Mainboard mainboard;public void setMainboard(Mainboard mainboard) {this.mainboard = mainboard;}public void doWork() {System.out.println("开始工作");for (int i = 0; i < 10; i++) {System.out.println("第" + i + "次工作");}System.out.println("工作结束");}public void start() {mainboard.startPower();}public void shutdown() {mainboard.shutdownPower();}public double getPrice() {return mainboard.getPrice() + mainboard.getCpu().getPrice() + mainboard.getRam().getPrice();}public String getSetting() {String ret = "电脑组成如下!主板:" + mainboard.getName() + ",CPU:" + mainboard.getCpu().getName() + ",内存:" + mainboard.getRam().getName() + "\n";ret += "这个配置的价格为:"+getPrice();return ret;}
}

主板MainBoard的设计及实现

在现实中,有很多种类型的主板,只要这些主板符合我们的标准,就能接到我们的电脑中来用。本例提供了AUSUBoard及IntelBoard两种类别的主板。

image

package com.computer.component;public class AbstractMainboard implements Mainboard {private CPU cpu;private Ram ram;    private boolean power;public void setCpu(CPU cpu) {this.cpu=cpu;}public CPU getCpu() {    return cpu;}public void setRam(Ram ram) {this.ram=ram;}public Ram getRam() {    return ram;}public boolean havePower() {return power;}public void startPower() {power=true;}public void shutdownPower() {power=false;}
}
package com.computer.component;public class AUSUBoard extends AbstractMainboard {public String getName() {return "AUSU主板";}public double getPrice() {return 3000.00;}public String getCompany() {return "SUSU公司";}    
}
package com.computer.component;public class IntelBoard extends AbstractMainboard {public String getName() {return "Intel主板";}public double getPrice() {return 3500.00;}public String getCompany() {return "Intel公司";}    
}

CPU的设计及实现

在现实中,有很多种类型的CPU可供使用,只要这些CPU符合我们的标准,就能接到我们的电脑中来用。本例提供了AMDCpu及IntelCPU两种类别的CPU。

image

package com.computer.component;public class IntelCPU implements CPU {public int getSpeed() {return 1700;}public void doInstr() {System.out.println("做指令运算");        }public void outResult() {    }public String getName() {    return "IntelCPU";}public double getPrice() {return 2500;}public String getCompany() {    return "Intel公司";}
}
package com.computer.component;public class AMDCpu implements CPU {public int getSpeed() {return 1500;}public void doInstr() {System.out.println("做指令运算");        }public void outResult() {        }public String getName() {    return "AMD CPU";}public double getPrice() {return 1800;}public String getCompany() {    return "AMD公司";}
}

内存的设计及实现

本例我们也只提供两款可供选择的内存。分别是Kingmax的内存,以及Kingstone的内存。

image

package com.computer.component;public class KingstoneRam implements Ram {public int getSize() {        return 512;}public void inData() {//读入数据}public void outData() {//输出数据}public String getName() {return "Kingstone内存";}public double getPrice() {    return 200;}public String getCompany() {    return "Kingstone公司";}
}
package com.computer.component;public class KingmaxRam implements Ram {public int getSize() {        return 512;}public void inData() {//读入数据}public void outData() {//输出数据}public String getName() {return "Kingmax内存";}public double getPrice() {    return 300;}public String getCompany() {    return "Kingmax公司";}
}

传统的组装电脑方法

传统的情况下,要组装一台电脑,需要在代码中分别new出每一个电脑组件的实例,再把他们组装到电脑上面,再运行程序。

package com.computer.computer;import com.computer.component.*;public class ClientOldDemo {public static void main(String[] args) {        CPU cpu=new IntelCPU();Ram ram=new KingmaxRam();Mainboard myMainboard=new IntelBoard();myMainboard.setCpu(cpu);myMainboard.setRam(ram);Computer computer=new Computer();computer.setMainboard(myMainboard);//执行computer的doWork方法,使得commputer开始工作computer.doWork();//输出电脑的配置信息System.out.println(computer.getSetting());    }
}

用Spring组装电脑

在Spring中,它会认为一切java类都是资源,而资源都是Bean,容纳这些Bean的是Spring所提供的IoC容器,所以Spring是一种基于Bean的编程。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="intelCpu" class="com.computer.component.IntelCPU" /><bean id="admCpu" class="com.computer.component.AMDCpu" /><bean id="kingstoneRam" class="com.computer.component.KingstoneRam" /><bean id="kingmaxRam" class="com.computer.component.KingmaxRam" /><bean id="intelBoard" class="com.computer.component.IntelBoard" ><property name="cpu" ref="intelCpu" /><property name="ram" ref="kingstoneRam" /></bean><bean id="ausuBoard" class="com.computer.component.AUSUBoard" ><property name="cpu" ref="admCpu" /><property name="ram" ref="kingmaxRam" /></bean><bean id="computer" class="com.computer.computer.Computer" ><property name="mainboard" ref="intelBoard" /></bean><bean id="myMainboard" class="com.computer.component.IntelBoard"><property name="ram" ><bean class="com.computer.component.KingmaxRam"/></property><property name="cpu" ><bean class="com.computer.component.IntelCPU"/></property></bean><bean id="myComputer" class="com.computer.computer.Computer"><property name="mainboard" ref="myMainboard"/></bean>
</beans>

在配置文件中,通过<bean>标签来定义了一个id为myMainboard的主板,一个id为myComputer的电脑。通过<bean>标签下的<property>分别设置了主板上选择的具体的内存Ram及CPU,另外还通过myComputer的<property>标签设置了mainboard属性为myMainboard。

使用Spring组装好的电脑

package com.computer;import com.computer.computer.Computer;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class ClientDemo {public static void main(String[] args) {var context = new ClassPathXmlApplicationContext("spring-beans.xml");var computer = context.getBean("computer", Computer.class);computer.doWork();System.out.println(computer.getSetting());}
}

发布电脑组装程序(让用户自己组装电脑==>修改xml文件即可,无需修改代码)

ClientDemo相当于电脑的最终使用者,一个不会组装电脑的用户,其甚至不知道电脑由哪些部件组成,他需要的仅仅是一个完整可以正常工作的电脑;而负责维护Spring配置文件者,相当于组装电脑的一般技术人员,他不需要很高深的技术,不需要知道怎么样生产一块主板、生产一块CPU,只需要知道什么是主板,什么是CPU,什么是Ram,并且知道CPU及Ram应该插放在什么位置,知道主板怎么安装即可。而实现CPU接口、Mainboard接口及Ram内存的类编写人员,如编写InterCPU这个类的人员,就相当CPU厂家的一线专业技术工程师,他们需要对微电子、数据电路等很多非常专业的技术,他们需要对CPU的工作原理等非常了解。

image

基于上面的实例,可以基本上把控制反转定义为:控制反转是一种通过描述(在java中可以是xml或者注解)并通过第三方(spring容器)去产生或获取特定对象的方式。

正如被动创建的电脑,是通过下面的xml代码描述所得到的:

<bean id="myComputer" class="edu.uestc.avatar.Computer"> 
<property name="mainboard" ref="myMainboard"/> 
</bean>

在spring中实现控制反转的是IoC容器,其实现方法是依赖注入。Spring会提供IoC容器来管理对应的资源,正如上面示例中的电脑和主板资源,他们形成依赖注入的关系。其中主板用到CPU和RAM两个资源。

为什么要使用Spring

在项目中引入spring立即可以带来下面的好处:

  • 降低组件之间的耦合度,实现软件各层之间的解耦,有利于测试。
  • 可以使用容器提供的众多服务,如:事务管理服务、消息服务等等。当我们使用容器管理事务时,开发人员就不再需要手工控制事务,也不需处理复杂的事务传播。
  • 容器提供单例模式支持,开发人员不再需要自己编写实现代码。
  • 容器提供了AOP技术,利用它很容易实现如权限拦截、运行期监控等功能。
  • 容器提供的众多辅作类,使用这些类能够加快应用的开发,如:JdbcTemplate、HibernateTemplate。
  • Spring对于主流的应用框架提供了集成支持,如:集成Hibernate、JPA、Struts等,这样更便于应用的开发。
  • Spring能通过接口而不是类促进好的编程习惯,降低开发难度。

image

http://www.jsqmd.com/news/109488/

相关文章:

  • 针对Docker CentoS Stream9内核和文件描述符优化
  • 从入门到精通:MCP DP-420图Agent备份技术深度拆解(仅限专业人士参考)
  • SKYNET Steam模拟器:如何在无网络环境下实现完美局域网游戏联机?
  • SPXO,VCXO,TCXO晶振讲解
  • MCP续证培训课程全曝光,这些隐藏考点你必须掌握
  • 安徽省黄山市自建房设计公司哪家强?2025最新评测排行榜 + 5 星企业推荐 - 苏木2025
  • 为什么MCP SC-400成为量子加密首选平台?(独家技术内幕曝光)
  • “中国甜糯玉米之乡”香飘荆楚 五寨区域公用品牌亮相武汉粮油展
  • 量子加密落地难题,MCP SC-400究竟解决了什么?
  • 海关申诉律师推荐:专业法律服务选择参考 - 品牌排行榜
  • 保姆级解析!Attention Weights 和 Attention是啥?到底怎么算?
  • 滁州市自建房设计公司权威评测排行榜:6大维度打分,5星企业全解析 - 苏木2025
  • MCP量子认证通过率仅35%?,靠这4套精准模拟题我一次上岸
  • React Flow v12 自定义节点连接边失效:5步诊断与修复指南
  • PS2数据流检测状态机-HDLbits
  • 职业技能学习路径规划工具,用户输入目标岗位,如AI工程师,结合现有技能水平,推荐分阶段学习资源(课程/书籍/项目),设置学习进度提醒。
  • 定制水服务:桶装、瓶装、纯净水及矿泉水定制,含Logo设计 - 品牌推荐大师
  • 为什么你的MCP MS-720 Agent总是无法正常通信?调试工具使用不当是主因?
  • 茄子婚庆:以创新模式重塑婚庆行业生态 - 资讯焦点
  • AI Agent高并发场景崩溃?你必须知道的6个性能监控指标
  • Illustrator自动化革命:80+脚本让你的设计效率飙升
  • 2025年12月旅行社,云南旅行社,昆明旅行社厂商推荐:聚焦企业综合实力与定制服务力 - 品牌鉴赏师
  • 长和宋实探:四大国企联袂,浏阳河畔的宋式美学藏品 - 资讯焦点
  • 终极解决方案:让Windows系统链接真正服从你的浏览器选择
  • 2025年最新AI编程工具权威评测:这九款利器让编程效率倍增
  • 中国eSIM领先厂商推荐权威榜单 - 品牌评测官
  • 强烈建议收藏!面向初创团队与独立开发者的AI编程软件精选
  • 2025年不锈钢小零件粉末冶金,小零件粉末冶金,粉末冶金厂家推荐,解析防锈处理与尺寸公差控制 - 品牌鉴赏师
  • MCP DP-420图Agent备份全解析:如何在30分钟内完成全流程部署
  • 2025年铠装缝,变形缝,金刚砂厂家推荐,解读地坪防护与耐磨性能双重适配方案 - 品牌鉴赏师