Java阶段三02
第3章-第2节
一、知识点
面向接口编程、什么是spring、什么是IOC、IOC的使用、依赖注入
二、目标
-
了解什么是spring
-
理解IOC的思想和使用
-
了解IOC的bean的生命周期
-
理解什么是依赖注入
三、内容分析
-
重点
-
了解什么是spring
-
理解IOC的思想
-
掌握IOC的使用
-
-
难点
-
理解IOC的思想
-
掌握IOC的使用
-
四、内容
1、Spring
1.1 简介
spring是分层的java SE/EE应用full-stack轻量级开源框架,以IOC(Inverse Of Control:控制反转)和AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层Spring MVC和持久层Spring JDBC以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE企业级应用开源框架。
1.2 优势
-
开源免费的轻量级框架
-
低侵入式设计,代码污染极低
-
支持事务的处理,对框架整合的支持
-
以控制反转(IOC),面向切面编程(AOP)为内核
-
方便解耦,简化开发:将对象的创建交给spring 无需new
-
提供了展现层SpringMVC和持久层Spring JDBCTemplate以及业务层事务管理等众多企业级应用技术
-
能整合开源世界众多第三方框架和类库
1.3 引入依赖
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.11.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.6</version>
</dependency>
2、Ioc
2.1 概念
控制反转(IoC,Inversion of Control)是一个概念,是一种思想。指将传统上由程序代码直接操控的对象调用权交给容器,通过容器来实现对象的装配和管理。控制反转就是对对象控制权的转移,从程序代码本身反转到了外部容器。通过容器实现对象的创建,属性赋值,依赖的管理。
以前我们在代码中,使用new 构造方法创建对象,现在不用了, 由容器代替开发人员管理对象。
2.2 传统方式和ioc方式的区别
-
传统
我们要实现某一个功能或者说是完成某个业务逻辑时至少需要两个或以上的对象来协作完成,每个对象在需要使用他的合作对象时,自己均要使用像new object() 这样的语法来将合作对象创建出来,这个合作对象是由自己主动创建出来的,创建合作对象的主动权在自己手上,自己需要哪个合作对象,就主动去创建,创建合作对象的主动权和创建时机是由自己把控的,而这样就会使得对象间的耦合度高了,A对象需要使用合作对象B来共同完成一件事,A要使用B,那么A就对B产生了依赖,也就是A和B之间存在一种耦合关系,并且是紧密耦合在一起。
-
ioc
创建合作对象B的工作是由Spring来做的,Spring创建好B对象,然后存储到一个容器里面,当A对象需要使用B对象时,Spring就从存放对象的那个容器里面取出A要使用的那个B对象,然后交给A对象使用,至于Spring是如何创建那个对象,以及什么时候创建好对象的,A对象不需要关心这些细节问题(你是什么时候生的,怎么生出来的我可不关心,能帮我干活就行),A得到Spring给我们的对象之后,两个人一起协作完成要完成的工作即可。
下面用制造汽车需要引擎、轮胎等零件的场景解释含义
-
假设现在要生产汽车、货车、客车、出租车,它们都是使用【1代引擎】
代码如下:
public class EngineV1 {
private String name = "1代引擎";
public String getName() {return name;}
}
/*** 汽车*/
public class Car {
private String carName = "小汽车";
private EngineV1 engineV1;
public Car(EngineV1 engineV1) {this.engineV1 = engineV1;}
public void info() {System.out.println(carName + "使用的是" + engineV1.getName());}
}
/*** 货车*/
public class Van {
private String carName = "货车";
private EngineV1 engineV1;
public Van(EngineV1 engineV1) {this.engineV1 = engineV1;}
public void info() {System.out.println(carName + "使用的是" + engineV1.getName());}
}
测试
Car car = new Car(new EngineV1());
car.info();
Van van = new Van(new EngineV1());
van.info();
// 结果
// 小汽车使用的是1代引擎
// 货车使用的是1代引擎
总结:现在可以看出不管是汽车还是货车,都是依赖于【1代引擎】的,耦合度很高,没有【1代引擎】就没有这些车。假如我们还有很多其他类型的车都是依赖于【1代引擎】,有一天我想把所有的【1代引擎】换成 【2代引擎】我该怎么做?全局搜索【1代引擎】修改为 【2代引擎】,想想都有点麻烦。
-
我们需要换一种思路来实现,解决上述问题。
/*** 引擎接口*/
public interface IEngine {String getName();
}
public class EngineV1 implements IEngine{
private String name = "1代引擎";
public String getName() {return name;}
}
public class EngineV2 implements IEngine{
private String name = "2代引擎";
public String getName() {return name;}
}
/*** 汽车*/
public class Car {
private String carName = "小汽车";
// 现在不依赖于具体哪个引擎,直接对接引擎接口private IEngine engine;
public Car(IEngine engine) {this.engine = engine;}
public void info() {System.out.println(carName + "使用的是" + engine.getName());}
}
/*** 货车*/
public class Van {
private String carName = "货车";
private IEngine engine;
public Van(IEngine engine) {this.engine = engine;}
public void info() {System.out.println(carName + "使用的是" + engine.getName());}
}
测试
Car car = new Car(new EngineV1());
car.info();
Van van = new Van(new EngineV1());
van.info();
// 结果
// 小汽车使用的是1代引擎
// 货车使用的是1代引擎
Car car = new Car(new EngineV2());
car.info();
Van van = new Van(new EngineV2());
van.info();
// 结果
// 小汽车使用的是2代引擎
// 货车使用的是2代引擎
总结:代码中不再依赖于具体,而是依赖于抽象容器,即要针对接口编程,不针对实现编程。过去思维中想要什么依赖,需要自己去 “拉” 改为抽象容器主动 “推” 给你,你只管使用实体就可以了。这是依赖倒转 (DIP) 的一种表现形式。由原来的汽车依赖引擎转化成了引擎依赖引擎接口了,进行了反转。现在生产汽车的时候,给汽车什么引擎它就用什么引擎,汽车就脱离了只能用【1代引擎】绝对绑定形式了。
我们还可以接着优化,现在是使用引擎的时候我们手动去new的。假如项目中有很多的地方使用了【1代引擎】,要换成【2代引擎】,即把全部的new EngineV1()
改成new EngineV2()
。
-
针对上面的问题进行优化。我们可以先创建一个仓库出来,把引擎先创建好放在容器里面。车辆要用引擎的时候直接从仓库里面获取。
/*** 容器*/
public class Container {
private Map<String, Object> map = new HashMap<String, Object>();
public Container() {// 此处利用可以利用读取配置的方式,利用反射动态创建出对象map.put("engine", new EngineV1());}
public Object getBean(String name) {return map.get(name);}
}
测试
// 创建容器
Container container = new Container();
Car car = new Car((IEngine) container.getBean("engine"));
car.info();
Van van = new Van((IEngine) container.getBean("engine"));
van.info();
// 结果
// 小汽车使用的是1代引擎
// 货车使用的是1代引擎
现在要把【1代引擎】化成【2代引擎】,我们只需要修改容器里面的引擎即可,只要修改一处地方。
map.put("engine", new EngineV2());
上面的测试结果就变成了
// 创建容器
Container container = new Container();
Car car = new Car((IEngine) container.getBean("engine"));
car.info();
Van van = new Van((IEngine) container.getBean("engine"));
van.info();
// 结果
// 小汽车使用的是2代引擎
// 货车使用的是2代引擎
总结:这就是IOC要做的事情。把创建对象的过程交给spring管理,我们需要用的时候直接拿就行。
3、基本使用
3.1 方式一:配置文件
-
创建xml文件 resources/文件名.xml
-
创建类
-
xml配置
<!-- id:spring生成对象的时候,放到容器里面,会给每一个对象生成一个id,用于区分对象 --> <!-- class:告诉它使用哪个类 --> <bean id="student" class="com.company.eneity.Student">
-
获取对象
-
通过id获取
public static void main(String[] args) {// 生成spring容器// 读取spring的xml文件,根据内容生成对应的对象,放到容器里面ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");// 获取对象,传入id,通过id获取对象Student student = (Student) ctx.getBean("student");System.out.println(student); }
-
通过类获取
public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");Student student1 = ctx.getBean(Student.class);System.out.println(student1); }
-
3.2 方式二:注解
-
创建类
// spring扫描到这个注解的时候,会自动生成对象 @Component public class Teacher {}
-
配置xml的component-scan
<!-- 扫描包,会去扫描注解,有对应注解的会自动生成对象 --> <context:component-scan base-package="com.company"></context:component-scan>
-
获取对象
@Component public class TeacherDao {private Teacher teacher;public void test(){System.out.println(teacher);} } ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml"); TeacherDao teacherDao = ctx.getBean(TeacherDao.class); teacherDao.test(); 3.3 bean的生命周期
spring默认的是单例对象可以通过scope修改
-
单例对象
scope="singleton"
创建bean的时候使用默认的无参构造函数
一个应用只有一个对象的实例,它的作用范围就是整个应用
生命周期
对象出生:当应用加载,创建容器时,对象就被创建
对象活着:只要容器在,对象一直活着
对象死亡:当应用卸载,销毁容器时,对象就被销毁了
测试
// 创建spring容器 // 创建容器的时候,对象已经生成 ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml"); // 获取对象只是从容器里面拿出来 Student student1 = (Student) ctx.getBean("student"); Student student2 = (Student) ctx.getBean("student"); System.out.println(student1 == student2); // 结果 true
-
多例对象
scope="prototype"
每次访问对象时,都会被重新创建对象实例
生命周期
对象出生:当使用对象时,创建新的对象实例
对象活着:对象在使用中,对象就一直活着
对象死亡:当对象长时间不用,被java垃圾回收机制回收
测试
// 创建spring容器 // 创建容器的时候对象还没有生成 ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml"); // 获取对象的时候才创建对象 Student student1 = (Student) ctx.getBean("student"); Student student2 = (Student) ctx.getBean("student"); System.out.println(student1 == student2); // 结果 false
4、依赖注入
IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。
4.1 使用构造函数
前提:类中需要提供一个对应参数列表的构造函数
标签:constructor-arg
标签属性:
index:指定参数在构造函数参数列表中的索引位置
type:指定参数在构造函数中的数据类型
name:指定参数在构造函数中的名称,用这个找给谁赋值
value:它能赋的值是基本数据类型和String类型
ref:它能赋的值是其他bean类型,也就是说,必须得是在配置文件中配置过的bean
-
基本数据类型(数值类和字符串类)
基本数据类型直接用value赋值
<bean id="student" class="com.company.eneity.Student"><!-- constructor-arg调用有参否则函数,必须有写构造函数 --><constructor-arg name="name" value="张三"></constructor-arg><constructor-arg name="age" value="18"></constructor-arg> </bean>
-
引用数据类型
引用数据类型使用ref赋值
<bean id="student" class="com.company.eneity.Student"><!-- constructor-arg调用有参否则函数,必须有写构造函数 --><constructor-arg name="name" value="张三"></constructor-arg><constructor-arg name="age" value="18"></constructor-arg><constructor-arg name="studentMarjor" ref="studentMarjor"></constructor-arg> </bean>
4.2 使用set赋值
标签:property
标签属性:
name:找的是类中set方法后面的部分
value:给属性赋值的是基本数据类型和String类型
ref:给属性赋值是其他bean类型的
-
基本数据类型
<bean id="student2" class="com.company.eneity.Student2"><!-- property调用set的方法,必须set方法 --><property name="name" value="张三"></property><property name="age" value="18"></property> </bean>
-
引用数据类型
<bean id="student" class="com.company.eneity.Student"><property name="name" value="张三"></property><property name="age" value="18"></property><property name="studentMarjor" ref="studentMarjor"></property> </bean> <bean id="studentMarjor" class="com.company.eneity.StudentMarjor"><property name="name" value="软件工程"></property><property name="studentNum" value="80"></property> </bean>
5、小结
本章节中我们学习了什么是Spring,spring的优势是什么,为什么要用spring,同时学习了spring的一个核心功能IOC(控制反转),理解了控制反转的作用以及为什么要用控制反转,同时理解了什么是依赖注入,学会了通过XML文件配置IOC和不同方式的依赖注入。
下一节中,我们将会学习一些Spring的常用注解,学会使用注解进行开发,去理解注解开发和配置文件开发的区别和优势。
相关文章:
Java阶段三02
第3章-第2节 一、知识点 面向接口编程、什么是spring、什么是IOC、IOC的使用、依赖注入 二、目标 了解什么是spring 理解IOC的思想和使用 了解IOC的bean的生命周期 理解什么是依赖注入 三、内容分析 重点 了解什么是spring 理解IOC的思想 掌握IOC的使用 难点 理解IO…...
【Linux】掌握库的艺术:我的动静态库封装之旅
🌈个人主页:Yui_ 🌈Linux专栏:Linux 🌈C语言笔记专栏:C语言笔记 🌈数据结构专栏:数据结构 🌈C专栏:C 文章目录 1.什么是库1.2 认识动静态库1.2.1 动态库1.2.2…...
UE5动画控制 基础
素材 mixamo先去选择一个character 点击下载 就这个下载下来 然后选几个animation, 记得勾选 把动作下载了 without skin就是只要动作 然后把他们放在一个文件夹里先 UE里导入 找一个文件夹,直接拖拽进来那个character的fbx,默认配置就…...
流畅!HTMLCSS打造网格方块加载动画
效果演示 这个动画的效果是五个方块在网格中上下移动,模拟了一个连续的加载过程。每个方块的动画都是独立的,但是它们的时间间隔和路径被设计为相互协调,以创建出流畅的动画效果。 HTML <div class"loadingspinner"><…...
linux命令之top(Linux Command Top)
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…...
数据结构-希尔排序(ShellSort)笔记
看动画理解 【数据结构】八大排序(超详解附动图源码)_数据结构排序-CSDN博客 一 基本思想 先选定一个整数gap,把待排序文件中所有记录分成gap个组,所有距离为gap的记录分在同一组内,并对每一组内的元素进行排序。 然后将gap逐渐减小重复上…...
Junit + Mockito保姆级集成测试实践
一、做好单测,慢即是快 对于单元测试的看法,业界同仁理解多有不同,尤其是在业务变化快速的互联网行业,通常的问题主要有,必须要做吗?做到多少合适?现在没做不也挺好的吗?甚至一些大…...
软件项目管理要点
一.项目管理 1.盈亏平衡分析 销售额固定成本可变成本税费利润 当利润为0的时候就是盈亏平衡点。 2.范围管理 范围定义的输入包括:项目章程、项目范围管理计划、组织过程资产、批准的变更申请。 3.时间管理 项目时间管理中的过程包括活动定义、活动排序、活动的资…...
ESP8266 连接 MQTT 服务器EMQX 连接MQTTX
目录 1.先用有一台自己的云服务器 2. 使用FinalShell连接阿里云云服务器ECS 3.安装宝塔 4.在云服务器打开8888端口 5.使用外网面板地址打开宝塔面板 6.安装Docker 7.下载emqx 8.打开emqxWeb 界面 9.下载MQTTX 10.EMQX加一个客户端 11.开始通信 12.加入单片机ESP8266 …...
Python中如何处理异常情况?
1、Python中如何处理异常情况? 在Python中,处理异常情况通常使用try/except语句。try语句块包含可能会引发异常的代码,而except语句块包含处理异常的代码。如果try块中的代码引发了异常,控制流将立即转到相应的except块。 以下是…...
openpnp - 在openpnp中单独测试相机
文章目录 openpnp - 在openpnp中单独测试相机概述笔记END openpnp - 在openpnp中单独测试相机 概述 底部相机的位置不合适, 重新做了零件,准备先确定一下相机和吸嘴的距离是多少才合适。 如果在设备上直接实验,那么拆装调整相机挺麻烦的。 准备直接在电…...
Spark窗口函数
1、 Spark中的窗口函数 窗口就是单纯在行后面加一个列 可以套多个窗口函数,但彼此之间不能相互引用,是独立的 窗口函数会产生shuffle over就是用来划分窗口的 (1) 分组聚合里面的函数,基…...
Idea、VS Code 如何安装Fitten Code插件使用
博主主页:【南鸢1.0】 本文专栏:JAVA 目录 编辑 简介 所用工具 1、Idea如何安装插件 1.idea下载插件 2.需要从外部下载然后在安装, 2、VS Code如何安装插件 总结 简介 Fitten Code是由非十大模型驱动的AI编程助手,它可以自动生成代…...
elasticsearch7.x在k8s中的部署
一、说明 二、思路 三、部署 1、建nfs服务器 2、建持久卷 3、部署elasticsearch 四、附件 ?pv.yaml内容 elasticsearch.yaml内容 一、说明 本文章内容主要的参考来源是https://www.cnblogs.com/javashop-docs/p/12410845.html,但参考文献中的elasticsearc…...
校园社团信息管理平台:Spring Boot技术实战指南
3系统分析 3.1可行性分析 通过对本校园社团信息管理系统实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本校园社团信息管理系统采用SSM框架,JAVA作…...
【Linux】从内核角度理解 TCP 的 全连接队列(以及什么是 TCP 抓包)
文章目录 概念引入理解全连接队列内核方面理解Tcp抓包方法注意事项 概念引入 我们知道,TCP的三次握手是由TCP协议 自动处理的,建立连接的过程与用户是否进行accept无关,accept()的作用主要是为当前连接创建一个套接字,用于进行后…...
太速科技-712-6U VPX飞腾处理器刀片计算机
6U VPX飞腾处理器刀片计算机 一、产品概述 该产品是一款基于国产飞腾FT-2000四核处理器或D2000八核处理器的高性能6U VPX刀片式计算机。产品提供了可支持全网状交换的高速数据通道,其中P1、P2均支持1个PCIe x16 Gen3或2个PCIe x8 Gen3或4个PCIe x4 Gen3总…...
深度学习(八) TensorFlow、PyTorch、Keras框架大比拼(8/10)
一、深度学习框架概述 深度学习框架在当今人工智能和机器学习领域中占据着至关重要的地位。其中,TensorFlow 由 Google 开发,自 2015 年发布以来,凭借其灵活的计算图、自动微分功能以及跨平台支持等特点,迅速成为主流深度学习框架…...
thinkphp中命令行工具think使用,可用于快速生成控制器,模型,中间件等
在使用tp框架的时候tp内置了一个think的命令行工具, 这个工具可以帮助我们快速的生成控制器,模型,中间件的代码。 这个工具就和laravel中的 artisan 的作用都差不多,只是名称不同而已。 tp中常用的命令行工具: 1. 快…...
Discourse 是否支持手机注册
Discourse 能不能使用手机进行注册? 功能总结 简答来说,Discourse 不能使用手机注册,Discourse 也没有提供这个功能。 这个功能多是需要 SSO 来实现。 比如说华为的那个社区,他们自己做了一个自己的用户管理 SSO,然…...
软件测试学习笔记丨Flask框架-请求与响应
本文转自测试人社区,原文链接:https://ceshiren.com/t/topic/23408 请求方法 from flask import Flaskapp Flask(__name__)app.route("/cases", methods["get"]) def get_case():return {"code": 0, "msg": &…...
【C++笔记】list结构剖析及其模拟实现
【C笔记】list结构剖析及其模拟实现 🔥个人主页:大白的编程日记 🔥专栏:C笔记 文章目录 【C笔记】list结构剖析及其模拟实现前言一 .list的结构及其介绍1.1list的结构1.2list的使用1.3迭代器划分 二.list的模拟实现2.1 list结构…...
C#进阶1
C#进阶1 本文章主要介绍C#的进阶知识,如反射,特性.... 参考视频链接 原码 文章目录 C#进阶1反射步骤泛型反射调用方法 获取属性 特性特性的定义步骤扩展枚举练习 反射 在 C# 中,反射(Reflection)是一种强大的机制&a…...
PHP如何对输出进行转义
在PHP中,对输出进行转义是为了防止跨站脚本攻击(XSS)和其他安全问题。PHP提供了多种函数来对输出进行转义,这些函数根据输出的上下文(如HTML、JavaScript、URL等)而有所不同。以下是一些常用的转义函数及其…...
Windows 10 安装Docker踩过的坑和解决-31/10/2024
目录 环境版本 一、Docker Desktop双击启动没反应,open //./pipe/dockerDesktopLinuxEngine: The system cannot find the file specified. 二、Docker Desktop运行run命令时显示错误HTTP code 500 并且错误大意是服务器拒绝访问 三、检测Docker是否可以正常使用…...
【应急响应】Linux植入恶意程序排查流程
文章目录 前言一、Linux入侵检查二、Linux系统被入侵/中毒有哪些现象三、Linux系统被入侵/中毒处置过程四、Linux安全防护措施五、服务器被GetShell渗透解决办法(案例)前言 本篇文章主要是以我们日常的运维工作中对Linux服务器进行安全检查,进一步介绍如何使用具体命令来对Li…...
微信小程序app.js里面onLaunch里面的函数比page里面的onshow里面的方法后执行
微信小程序app.js里面onLaunch里面的函数比page里面的onshow里面的方法后执行 我们在app.js里面执行登录时可以调用checkLoginReadyCallback wx.login({ success: (res) > { $api .login({ jsCode: res.code, }) .then((res1) > { wx.hideLoading(); if (res1.code 0) …...
斐波那契时间序列,精准捕捉市场拐点 MT4免费公式源码!
指标名称:斐波那契时间序列 版本:MT4 ver. 2.01 斐波那契时间序列是一种技术分析工具,通过将斐波那契数列(如1, 2, 3, 5, 8, 13等)应用于时间轴上,用于预测市场价格的时间周期拐点。斐波那契时间序列在股…...
计算机的错误计算(一百四十)
摘要 探讨 MATLAB 中函数 的计算精度。 从计算机的错误计算(一百三十九)知,对于对数运算,当真数在 1 附近时,计算机的输出会出现较大误差。为此,IEEE 754-2019 中专门定义有函数 其目的就是当自变量在 …...
JavaEE初阶---网络原理(四)--IP协议/DNS协议
文章目录 1.初识网络层(了解即可)2.地址管理2.1动态分配2.2网络地址转换2.3IP-v6最终解 3.网段划分4.以太网协议--数据链路层5.DNS应用层协议 1.初识网络层(了解即可) 网络层做的事情就是下面的两个: 1)地…...
网络运维工程师薪酬/徐州seo代理计费
1、单片机向上位机LabVIEW VISA串口不断发送数据,只要存在帧间隔,VISA就会每次只上来一帧,之后只要调用解析一帧的子VI程序就可以。关键在于如何保存解析过的每一帧数据。簇数组/数组簇?...
科技公司起名字大全免费/文军seo
入门 简单使用 <script src"../js/vue.js"></script><div id"app">{{message}}{{movies}} </div><script> const app new Vue({el:#app, //用于管理要管理的元素data:{ //定义数据 或者服务器请求数据message:你好啊,mo…...
优惠劵精选网站怎么做/营销与销售的区别
信号名 位宽 I/O 描述 clk 1 I 时钟 nrst 1 I 全局异步时钟,低电平有效,有效时所有寄存器清零 stall 1 I 暂停信号,该信号为1时,寄存器所有值保持不变 ren 1 I 读使能,高电平有效 radd1/radd2 5 …...
房产采集网站源代码/如何做线上销售和推广
六、Page Control1、安装packageControl(管理插件的工具)打开 https://packagecontrol.io/,点击右侧菜单installation根据版本及提示进行安装ctrl打开console,将import urllib.request,os,hashlib; h eb2297e1a458f27d836c04bb0cbaf282 d0e7a309809277…...
北京规划网站/长沙网站建设
一、前言在前一篇博客中,小编向大家介绍了《使用idea搭建SSM框架》,如果按照小编的步骤做下来,基本上是没有问题的。但是这个只是一个简单的SSM架构,在上线的项目中,这种架构只能满足一些用户量比较小的项目࿰…...
wordpress显示/成品短视频网站源码搭建
一行代码的事情,...