(一)Spring官网
Spring Framework - Spring Framework
目前(2022-5-27)Spring Framework版本是5.3.20
(二)Spring框架优点
Spring makes Java productive.
Spring makes Java reactive.
Spring makes Java cloud-ready.
Spring makes Java simple.
Spring makes Java modern.
(三)为什么要选择Spring?
Spring makes programming Java quicker, easier, and safer for everybody. Spring’s focus on speed, simplicity, and productivity has made it the world's most popular Java framework.
“We use a lot of the tools that come with the Spring framework and reap the benefits of having a lot of the out of the box solutions, and not having to worry about writing a ton of additional code—so that really saves us some time and energy.” —— SEAN GRAHAM, APPLICATION TRANSFORMATION LEAD, DICK’S SPORTING GOODS
访问迪克体育用品网站:https://www.dickssportinggoods.com
Spring框架有两个非常重要的特性:IoC(Inversion of Control - 控制反转)和AOP(Aspect-Oriented Programming - 面向切面编程)。
Spring容器其实就是一个Bean工厂,在工厂里通过配置文件或配置类创建各种各样的Bean,然后在Spring应用程序就可以按照名称或类型获取工厂里已经配置好的Bean。下面我们就通过一个具体的案例来了解Spring容器是如何工作的。
(二)创建Maven项目
- 创建Maven项目 -
SpringDemo
,设置项目位置以及组ID
单击【Finish】按钮
修改项目的Maven配置
(三)添加Spring依赖
-
在Maven仓库里查找Spring框架(https://mvnrepository.com)
查看Spring Core
选择最新版本 - 5.3.20
添加到pom.xml
文件的<dependencies>
元素里
-
同理添加其他依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>net.huawei.spring</groupId> <artifactId>SpringDemo</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!--Spring核心--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.3.20</version> </dependency> <!--Spring实体--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.3.20</version> </dependency> <!--Spring容器--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.20</version> </dependency> <!--Spring Web--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.3.20</version> </dependency> <!--Spring MVC--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.20</version> </dependency> <!--Spring测试--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.3.20</version> </dependency> <!--单元测试--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13</version> <scope>test</scope> </dependency> </dependencies> </project>
-
但是大家可以看到版本号是红色的,说明这些依赖包还没有下载
-
打开Maven窗口
单击刷新按钮,就开始下载依赖包
等待插件与依赖下载完成(第一次下载有点慢,需要耐心等待)
查看本地Maven仓库
可以查看项目下载的有关Spring框架的依赖
(三)创建杀龙任务类
创建
net.huawei.spring.day01
包,然后在包里面创建SlayDragonQuest
类(四)创建勇敢骑士类
在net.huawei.spring.day01包里创建BraveKnight类package net.huawei.spring.day01;
/**
* 功能:勇敢骑士类
* 作者:华卫
* 日期:2022年05月27日
*/
public class BraveKnight {
// 勇敢骑士姓名
private String name;
// 创建杀龙任务对象
private SlayDragonQuest slayDragonQuest;public String getName() {
return name;
}public void setName(String name) {
this.name = name;
}/**
* 设置杀龙任务
*
* @param slayDragonQuest
*/
public void setSlayDragonQuest(SlayDragonQuest slayDragonQuest) {
this.slayDragonQuest = slayDragonQuest;
}/**
* 勇敢骑士执行任务
*/
public void embarkOnQuest() {
System.out.print("勇敢骑士[" + name + "]");
slayDragonQuest.embark(); // 执行杀龙任务
}
}回顾一下传统方式怎么使用这两个类。需要我们自己通过new实例化两个类,然后设置勇敢骑士对象的姓名和杀龙任务属性,然后调用勇敢骑士执行任务的方法。
(五)采用传统方式让勇敢骑士完成杀龙任务
在test/java里创建net.huawei.spring.day01包,然后在包里面创建TestBraveKnightOld类
package net.huawei.spring.day01;import org.junit.Test;
/**
* 功能:采用传统方式测试勇敢骑士类
* 作者:华卫
* 日期:2022年05月27日
*/
public class TestBraveKnightOld {
@Test
public void testBraveKnight() {
// 创建杀龙任务对象
SlayDragonQuest slayDragonQuest = new SlayDragonQuest();
// 创建勇敢骑士对象
BraveKnight braveKnight = new BraveKnight();
// 设置勇敢骑士属性
braveKnight.setName("罗宾汉");
braveKnight.setSlayDragonQuest(slayDragonQuest);
// 调用勇敢骑士执行任务方法
braveKnight.embarkOnQuest();
}
}
运行测试方法testBraveKnight()
运行测试方法testBraveKnight()查看程序运行结果
(六)采用Spring框架让勇敢骑士完成杀龙任务
1、创建日志属性文件
在resources目录里创建log4j.properties
log4j.rootLogger=WARN, stdout, logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spring.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n2、创建Spring配置文件
在resources里创建xmlconfig目录,然后在里面创建spring-config.xml输入Spring配置文件名
单击【Configure application context】(配置应用上下文)
)
单击【Create new application context…】(创建新的应用上下文),注意应用上下文名称是可以修改的
单击【OK】按钮
在项目结构窗口里查看配置好的spring-config.xml
现在我们有了生产Bean的车间,下面我们就要在车间里配置产品
3、在Spring配置文件里创建Bean
(1)创建杀龙任务Bean<!--杀龙任务Bean-->
<bean id="slayDragonQuest" class="net.huawei.spring.day01.SlayDragonQuest"/>id属性 :对应对象名,可以任取,然后在应用程序里我们可以通过这个id值从Spring容器中获取Bean对象。
class属性 :表明Bean对象是基于哪个类来实例化,注意一定要包含包名。
(2)创建勇敢骑士Bean<!--创建勇敢骑士Bean-->
<bean id="RobinHood" class="net.huawei.spring.day01.BraveKnight">
<property name="name" value="罗宾汉"/> <!-- RobinHood.setName("罗宾汉")-->
<property name="slayDragonQuest" ref="slayDragonQuest"/> <!--RobinHood.setSlayDragonQuest(slayDragonQuest)-->
</bean>
property元素:给对象设置属性值
name属性:Bean对象的属性名
ref属性:Bean对象的属性值(引用另一个Bean对象)
勇敢骑士Bean通过<property>元素将杀龙任务Bean注入作为其属性。注意,name属性值一定是BraveKnight类的属性名,ref属性值是已定义的杀龙任务Bean的id值。
<?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-->
<bean id="slayDragonQuest" class="net.huawei.spring.day01.SlayDragonQuest"/>
<!--创建勇敢骑士Bean-->
<bean id="RobinHood" class="net.huawei.spring.day01.BraveKnight">
<property name="name" value="罗宾汉"/> <!-- RobinHood.setName("罗宾汉")-->
<property name="slayDragonQuest" ref="slayDragonQuest"/> <!--RobinHood.setSlayDragonQuest(slayDragonQuest)-->
</bean>
</beans>
通过Spring配置文件,创建了两个Bean对象,它们之间存在依赖关系,第一个Bean对象是第二个Bean对象的任务属性值。4、创建勇敢骑士测试类
在test/java/net.huawei.spring.day01里创建TestBraveKnightNew测试类 -
采用基于类路径的应用容器类 -
ClassPathXmlApplicationContext
package net.huawei.spring.day01; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * 功能:测试勇敢骑士类 * 作者:华卫 * 日期:2022年05月29日 */ public class TestBraveKnightNew { private ClassPathXmlApplicationContext context; // 基于类路径XML配置文件的应用容器 @Before // 每次测试方法执行前都要执行的代码 public void init() { // 基于Spring配置文件创建应用容器 context = new ClassPathXmlApplicationContext("xmlconfig/spring-config.xml"); // 提示用户 System.out.println("Spring应用容器已创建~"); } @Test public void testBraveKnight() { // 根据名称从应用容器中获取勇敢骑士对象(配置文件里定义勇敢骑士Bean的id是"RobinHood") BraveKnight braveKnight = (BraveKnight) context.getBean("RobinHood"); // 勇敢骑士执行任务 braveKnight.embarkOnQuest(); } @After // 每次测试方法执行后都要执行的代码 public void destroy() { // 关闭应用容器 context.close(); // 提示用户 System.out.println("Spring应用容器已关闭~"); } }
6、修改新勇敢骑士测试类
- 获取新建的两个勇敢骑士Bean,调用执行任务方法
-
执行
testKnight
测试方法,查看结果(七)采用构造方法注入方式注入属性值
1、创建救美任务类
在net.huawei.spring.day01包里创建RescueDamselQuest类
package net.huawei.spring.day01;
/**
* 功能:救美任务类
* 作者:华卫
* 日期:2022年05月29日
*/
public class RescueDamselQuest {
public void embark() {
System.out.println("执行救美任务……");
}
}2、创建救美骑士类
在net.huawei.spring.day01包里创建DamselRescuingKnight类package net.huawei.spring.day01; /** * 功能:救美骑士类 * 作者:华卫 * 日期:2022年05月29日 */ public class RescueDamselKnight { private String name; private RescueDamselQuest rescueDamselQuest; /** * 有参构造方法 * * @param name * @param rescueDamselQuest */ public RescueDamselKnight(String name, RescueDamselQuest rescueDamselQuest) { this.name = name; this.rescueDamselQuest = rescueDamselQuest; } public void embarkOnQuest() { System.out.print("救美骑士[" + name + ']'); rescueDamselQuest.embark(); } }
3、配置救美骑士Bean
- 在Spring配置文件里创建救美骑士Bean
-
4、创建旧救美骑士测试类
- 在
test/java/net.huawei.spring.day01
包里创建TestRescueDamselKnightOld
类 -
package net.huawei.spring.day01; import org.junit.Test; /** * 功能:传统方式测试救美骑士类 * 作者:华卫 * 日期:2022年05月29日 */ public class TestRescueDamselKnightOld { @Test public void testRescueDamselKnight() { // 创建救美任务对象 RescueDamselQuest rescueDamselQuest = new RescueDamselQuest(); // 创建救美骑士对象 RescueDamselKnight rescueDamselKnight = new RescueDamselKnight("格拉海德", rescueDamselQuest); // 救美骑士执行任务 rescueDamselKnight.embarkOnQuest(); } }