Spring框架快速入门
目录
什么是Spring?
为什么学习Spring?
Spring的快速入门
Spring的版本
IOC概述
什么是IOC?
Spring的IoC入门
下载Spring的开发包
创建web项目,引入Spring的开发包
创建接口和实现类
编写测试类
Spring IoC和DI的区别
什么是Spring?
Spring是一个轻量级的Java开发框架。Spring的核心是控制反转(IoC)和面向切面(AOP),简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式)轻量级开源框架。
为什么说Spring是一个一站式的轻量级开源框架呢?EE开发可分成三层架构,针对JavaEE的三层结构,每一层Spring都提供了不同的解决技术。
从对Spring的简要介绍中,我们知道了Spring的核心有两部分:
IoC:即控制反转。举例来说,在之前的操作中,比方说有一个类,我们想要调用类里面的方法(不是静态方法),就要创建该类的对象,使用对象调用方法来实现。但对于Spring来说,Spring创建对象的过程,不是在代码里面实现的,而是交给Spring来进行配置实现的;
AOP:即面向切面编程。之前,讲Struts2框架的拦截器时,我们就已稍微讲了一下,在Spring后续的学习过程中,我们会着重来讲它,但是本文并不会过多阐述它。
为什么学习Spring?
1)方便解耦,简化开发
通过Spring提供的IOC容器,我们可以将对象之间的依赖关系交给Spring进行控制,避免硬编码所造成的的过度程序耦合。有了Spring,用户不必再为单实例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
2)AOP编程的支持
通过Spring提供的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应对。
3)声明式事务的支持
在Spring中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务的管理,提高开发效率和质量。
4)方便程序的测试
可以用废容器依赖的编程方式进行几乎所有的测试工作,在Spring里,测试不在是昂贵的操作,二十随手可做的事情。例如:Spring对Junit4支持,可以通过注解方便地测试Spring程序。
5)方便集成各种优秀框架
Spring不排斥各种优秀的开源框架,相反,Spring可以降低各种框架的使用难度,Spring提供了各种优秀框架(如Struts\Hibernate\Hessian\Quartz)等的直接支持。
6)降低Java EE API的使用难度
Spring对很多难用的Java EE API(如JDBC,JavaMail,远程调用等)提供了一个薄薄的封装层,通过Spring的简易封装,这些Java EE API的使用难度大为降低。
Spring的快速入门
Spring的版本
需要说明的是,本系列入门Spring的教程使用的版本是spring-framework-4.2.4.RELEASE。
IOC概述
什么是IOC?
IoC即Inversion of Control,反应过来就是控制反转。啥是控制反转啊?控制反转指的就是将对象的创建权反转给(交给)了Spring,其作用是实现了程序的解耦合。也可这样解释:获取对象的方式变了,对象创建的控制权不是"使用者",而是"框架"或者"容器"。用更通俗的话来说,IoC就是指对象的创建,并不是在代码中用new操作new出来的,而是通过Spring进行配置创建的。
Spring的IoC的底层实现原理
这里先给出结论:Spring的IoC的底层实现原理是工厂设计模式+反射+XML配置文件。 就拿持久层(也即dao层,data access object,数据访问对象)的开发来说,官方推荐做法是先创建一个接口,然后再创建接口对应的实现类。所以,这里,我会以dao层的开发为例来证明Spring的IoC的底层实现原理就是工厂设计模式+反射+XML配置文件。
首先,创建一个Userdao接口。
public interface UserDao {public void add();
}
然后,再创建Userdao接口的一个实现类(UserDaoImpl.java)。
public class UserDaoImpl implements UserDao {public void add() {balabala......}
}
接着,我们在service层中调用dao层,核心代码如下:
// 接口 实例变量 = new 实现类
UserDao dao = new UserDaoImpl();
dao.add();
这时我们便可发现一个缺点:service层和dao层耦合度太高了,即接口和实现类有耦合(它俩之间的联系过于紧密),一旦切换底层实现类,那么就需要修改源代码,这真的不是一个好的程序设计,好的程序设计应当满足OCP原则(也即开闭原则),即在尽量不修改程序源代码的基础上对程序进行扩展。
出现的这个问题该如何解决呢?解决方法是使用工厂设计模式进行解耦合操作。所以,我们需要创建一个工厂类,在工厂类中提供一个方法,返回实现类的对象。
public class BeanFactory {// 提供返回实现类对象的方法public static UserDao getUserDao() {return new UserDaoImpl();}
}
这样,在service层中调用dao层的核心代码就变为了下面的样子。
UserDao dao = BeanFactory.getUserDao();
dao.add();
如若这样做,会发现又产生了一个缺点:现在接口和实现类之间是没有耦合了,但是service层和工厂类耦合了。如果真正想实现程序之间的解耦合,那么就需要使用到工厂设计模式+反射+XML配置文件了。所以,我们这里提供一个XML配置文件,并且该配置文件中有如下配置信息。
<bean id="userDao" class="com.meimeixia.dao.impl.UserDaoImpl" />
然后再来创建一个工厂类,在工厂类中提供一个返回实现类对象的方法,但并不是直接new实现类,而是使用SAX解析配置文件,根据标签bean中的id属性值得到对应的class属性值,使用反射创建实现类对象。
public class BeanFactory {public static Object getBean(String id) {// 1.使用SAX解析得到配置文件内容// 直接根据id值userDao得到class属性值String classvalue = "class属性值";// 2.使用反射得到对象Class clazz = Class.forName(classvalue);UserDaoImpl userDaoImpl = (UserDaoImpl)lazz.newInstance();return userDaoImpl;}
}
以上就是Spring的IoC的底层实现原理。
Spring的IoC入门
下载Spring的开发包
Spring的官网是https://spring.io/,Spring的开发包的下载地址是https://repo.spring.io/libs-release-local/org/springframework/spring/,上面说过,我下载的是spring-framework-4.2.4.RELEASE这个版本的Spring。解压缩之后,可发现Spring开发包的目录结构如下。
创建web项目,引入Spring的开发包
首先创建一个动态web项目,例如spring_demo01,然后导入Spring框架相关依赖jar包,要导入哪些jar包呢?这是一个问题。
由于我们只是初次入门Spring,所以也只是使用到了Spring的基本功能,从上图红框框中的部分可知,我们需要使用到下面的这4个jar包。
除此之外,还要导入Spring支持的日志jar包,也就是下面两个jar包。
关于以上两个jar包,我稍微做一下解释,com.springsource.org.apache.commons.logging-1.1.1.jar它里面都是一些接口,有接口,那当然要有实现类了,恰好,com.springsource.org.apache.log4j-1.2.15.jar里面就是那些接口的实现类。使用Log4j,我们可以查看到当前运行程序中对象创建的过程,也可以看到更详细的信息,Log4j适合使用在程序调试中。
导入完日志相关的jar包之后,我们还要导入日志记录文件,即在src目录下引入Log4j的配置文件(log4j.properties),该文件内容如下:
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c\:mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n### set log levels - for more verbose logging change 'info' to 'debug' ###
# error warn info debug trace
log4j.rootLogger= info, stdout
对以上日志记录文件,我会粗略讲解一下。
从上图可知,log4j.rootLogger就是用于设置日志的输出级别,那么日志的输出级别有几种呢?有如下5种。
创建接口和实现类
首先,在src目录下创建一个com.meimeixia.spring.demo01包,并在该包下创建一个名为UserDao的接口。
package com.meimeixia.spring.demo01;/*** 用户管理的dao层的接口* @author liayun**/
public interface UserDao {public void save();}
然后,在com.meimeixia.spring.demo01包下创建UserDao接口的一个实现类——UserDaoImpl.java。
package com.meimeixia.spring.demo01;
/*** 用户管理的dao层接口的实现类* @author liayun**/
public class UserDaoImpl implements UserDao {@Overridepublic void save() {System.out.println("UserDaoImpl中的save方法执行了......");}
}
将实现类交给Spring管理
首先,我们需要创建Spring的配置文件,Spring配置文件的名称和位置没有固定要求,一般建议把该文件放到src目录下面,名称可随便写,官方建议写成applicationContext.xml。然后我们还需要在配置文件中引入约束,Spring学习阶段的约束是schema约束。那么问题来了,这个约束又该怎么写呢?可参考docs\spring-framework-reference\html目录下的xsd-configuration.html文件,在其内容最后面找到如下内容。
将其复制黏贴到配置文件applicationContext.xml中,这样applicationContext.xml文件的内容就是下面的样子了。
<?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"></beans>
最后,咱还要将实现类交给Spring来管理,即在配置文件中配置对象的创建。
<?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"><!-- Spring入门的配置 --><bean id="userDao" class="com.meimeixia.spring.demo01.UserDaoImpl"></bean></beans>
编写测试类
我们要在Spring中写代码来实现获取applicationContext.xml文件中配置的对象,这段代码不要求大家重点掌握,只是用在测试中而已。这段代码主要用来解析Spring配置文件得到对象,但这个过程不需要我们写代码来实现了,Spring已经封装了一个对象来帮我们进行了这些操作,这个对象叫ApplicationContext,它就能实现这个功能。于是,我们需要在com.meimeixia.spring.demo01包下创建一个SpringDemo01的单元测试类。
package com.meimeixia.spring.demo01;import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;/*** Spring的入门* @author liayun**/
public class SpringDemo01 {/** 传统方式的调用*/@Testpublic void demo01() {UserDao userDao = new UserDaoImpl();userDao.save();}/** Spring的方式的调用*/@Testpublic void demo02() {//先要创建Spring的工厂ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");// classpath就是类路径,src目录下的文件最终要编译到类路径下UserDao userDao = (UserDao) applicationContext.getBean("userDao");userDao.save();}}
然后,运行以上demo02单元测试方法,Eclipse控制台就会打印如下内容。
注意:这里的applicationContext.xml是放在src下,可运行成功,否则下面这句话会报错。
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Spring IoC和DI的区别
IoC上面我已经讲过了,它指的就是将对象的创建权反转给(交给)了Spring。那DI又是什么鬼呢?DI,即Dependency Injection,翻译过来就是依赖注入,它指的就是Spring在管理某个类的时候会将该类依赖的属性注入(设置)进来,也就是说在创建对象的过程中,向类里面的属性中设置值。注意:依赖注入不能单独存在,须在控制反转基础之上完成,用更通俗点的话来说,就是注入类里面的属性值,不能直接注入,须创建类的对象再完成注入。
你还记得在面向对象设计的时候,类和类之间有几种关系吗?有3种,它们分别是:
- 依赖,由于下图中B类的方法用到了A类,所以此时就可以说B类依赖于A类;
- 继承(is a),这种关系我们应该是见的要吐了;
- 聚合(has a),它有松散和紧密之分。例如,球队得有一个守门员,即使这个球队没有了这个守门员,它也还是一个球队,所以它是松散的;人得有一个脑袋,此时它就是紧密的。
说了这么多,咱就通过一个案例来看看DI在程序的体现。现在,我们想要给UserDaoImpl这个实现类里面的某一个属性(例如String类型的name)设置值,该咋怎呢?首先,将UserDaoImpl这个实现类修改成下面这个样子。
package com.meimeixia.spring.demo01;
/*** 用户管理的dao层接口的实现类* @author liayun**/
public class UserDaoImpl implements UserDao {private String name;//提供set方法public void setName(String name) {this.name = name;}@Overridepublic void save() {System.out.println("UserDaoImpl中的save方法执行了......" + name);}
}
如果使用传统的方式来为UserDaoImpl实现类的name属性设置值,那么SpringDemo01单元测试类中的demo01方法就应该写成下面这个样子。
package com.meimeixia.spring.demo01;import org.junit.Test;
/*** Spring的入门* @author liayun**/
public class SpringDemo01 {/** 传统方式的调用*/@Testpublic void demo01() {/** 我想给这个类里面的某一个属性设置值,挺麻烦的!* * 1. 不能面向接口编程了* 2. 你还得手动调用set方法,也得去改变程序的源代码*/UserDaoImpl userDao = new UserDaoImpl();userDao.setName("李二");userDao.save();}
}
这样写,就有两个缺点,一是不能面向接口编程了,二是咱还得手动调用对象的set方法,这必然就涉及到要改变程序的源代码了,这是我们不能接受的!
如果使用了依赖注入,即在applicationContext.xml文件中为配置好的UserDaoImpl实现类的name属性注入一个值,那么情况就完全不同了,以上两个缺点也就不复存在了。
<?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"><!-- Spring入门的配置 --><bean id="userDao" class="com.meimeixia.spring.demo01.UserDaoImpl"><!-- DI:依赖注入 --><property name="name" value="李二" /></bean>
</beans>
此时,SpringDemo01单元测试类中的demo02方法依然不变,如下。
package com.meimeixia.spring.demo01;import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;/*** Spring的入门* @author liayun**/
public class SpringDemo01 {/** 传统方式的调用*/@Testpublic void demo01() { /** 我想给这个类里面的某一个属性设置值,挺麻烦的!* * 1. 不能面向接口编程了* 2. 你还得手动调用set方法,也得去改变程序的源代码*/UserDaoImpl userDao = new UserDaoImpl();userDao.setName("李二");userDao.save();}/** Spring的方式的调用*/@Testpublic void demo02() {//先要创建Spring的工厂ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");UserDao userDao = (UserDao) applicationContext.getBean("userDao");userDao.save();}
}
运行以上demo02单元测试方法,Eclipse控制台就会打印出如下内容。
版权声明:本文为CSDN博主「李阿昀」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yerenyuan_pku/article/details/69663685
Spring框架快速入门相关推荐
- 视频教程-Spring框架快速入门到精通-Java
Spring框架快速入门到精通 十年项目开发经验,主要从事java相关的开发,熟悉各种mvc开发框架. 王振伟 ¥18.00 立即订阅 扫码下载「CSDN程序员学院APP」,1000+技术好课免费看 ...
- Spring框架快速入门(Spring超全面讲解)
Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用. 本课程将深入浅出讲解Spring的核心技术IoC.AOP,剖析框架 ...
- Quartz 框架快速入门(四)
Spring的scheduling.quartz包中对Quartz框架进行了封装,使得开发时不用写任何QuartSpring的代码就可以实现定时任务.Spring通过JobDetailBean,Met ...
- 视频教程-Spring boot快速入门-Java
Spring boot快速入门 十年项目开发经验,主要从事java相关的开发,熟悉各种mvc开发框架. 王振伟 ¥12.00 立即订阅 扫码下载「CSDN程序员学院APP」,1000+技术好课免费看 ...
- Quartz 框架快速入门(二)
尽可能的用声明式处理软件配置,其次才考虑编程式的方式.在上一篇<Quartz 框架快速入门(一)>中,如果我们要在 Job 启动之后改变它的执行时间和频度,必须去修改源代码重新编译.这种方 ...
- Quartz 框架快速入门(三)
在前面两篇文章中简单介绍了在java应用程序中如何使用Quartz框架,这一篇中我们将看到如何在web环境下通过配置文件来完成Quartz的后台作业调度,而不必手工去创建Trigger和Schedul ...
- 【完结】给新手的12大深度学习开源框架快速入门项目
文/编辑 | 言有三 这是一篇总结文,给大家来捋清楚12大深度学习开源框架的快速入门,这是有三AI的GitHub项目,欢迎大家star/fork. https://github.com/longpen ...
- java day53【 Mybatis框架概述 、 Mybatis 框架快速入门、自定义 Mybatis 框架 】
第1章 框架概述 1.1 什么是框架 1.1.1 什么是框架 框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种 定义认为,框架是可被应用开发者定 ...
- spring boot 快速入门
文章来源:https://www.cnblogs.com/junyang/p/8151802.html spring boot入门 -- 介绍和第一个例子 "越来越多的企业选择使用sprin ...
最新文章
- 阿里程序员35岁P7!4年了晋升无望!明年股票拿完,年包腰斩!世界那么大,要不要去看看?...
- Struts 源码分析笔记1(尚无内容-请跳过,省得浪费时间)
- android技术下载
- 全球及中国冶金工业运行潜力与深度战略分析报告2022版
- t test table
- 为什么开了数据不能上网_Doinb和LCK选手双排为什么不能开语音?Doinb深夜道出实情...
- Hermes与开源的Solr、ElasticSearch的不同
- 20-forEach循环语句
- 关于eclipse项目红色感叹号的解决办法
- 石子合并问题--直线版(Hrbust-1818)
- 动画片动漫迷<未来的未来>高清图片壁纸
- 查看IIS进程所对应的应用程序池名称
- (20190401)IGS GNSS数据下载网址与下载说明
- 怎么隐藏电脑桌面计算机,电脑怎么隐藏桌面图标?
- 调试bootmgrwinload vistawin7 x86x64
- Windows应用商店下载安装Ubuntu
- 信息收集之网站镜像克隆
- Python中文分词库jieba用法代码示例
- 1155 服务器芯片组,2014年主流主板芯片组分析
- 批量取消bilibili关注
热门文章
- 在实体引用中,实体名称必须紧跟在 ‘’后面
- Android的WebView如何播放视频和全屏视频(腾讯X5内核)
- 轻量应用服务器 饥荒,饥荒服务端世界设置生成
- mcs51单片机嵌入式c语言习题,MCS-51单片机复习题参考题库.doc
- 普中tft彩屏驱动程序下载_tft彩屏驱动程序
- SecureBoost: A Lossless Federated Learning Framework论文笔记
- 一篇文章读懂《麦肯锡极简工作法》
- UG模具:简单的运动仿真!只需七步,就让轮子转起来!
- Golang DNS 随便写写
- java基础多线程抢红包_java多线程模拟抢红包功能