1 引言
本例子取自书籍《Spring in Action》1第4版。随书提供的代码需用gradle工具编译和运行,我认为该例子比较短小简单,改为手动编译和运行。
Spring是一个开源框架,它简化了Java企业应用的开发,其一大特点是依赖注入。这个词听起来有点唬人,实际上是非常简单和容易理解的。通俗地说,就是将程序中各个类之间的依赖关系以配置的方式松耦合,避免它们之间的硬编码耦合。本文的目的就是通过一个例子帮助大家理解Spring框架中的依赖注入机制。
下面例子所用的环境如下:
名称 | 版本 |
---|---|
JDK | 1.8.0_281 |
Spring | 4.1.1 |
2 例子
2.1 例子内容
本例子的文件夹结构为:
├── classes/
│ ├── sia/
│ └── knight.xml
├── lib/
├── src/
│ ├── sia/
│ │ ├──完整源代码文件
lib文件夹下存放是Spring相关的jar包,如下图所示:
Quest.java代码如下:
package sia.knights;
public interface Quest {
void embark();
}
SlayDragonQuest.java的代码如下:
package sia.knights;
import java.io.PrintStream;
public class SlayDragonQuest implements Quest {
private PrintStream stream;
public SlayDragonQuest(PrintStream stream) {
this.stream = stream;
}
public void embark() {
stream.println("Embarking on quest to slay the dragon!");
}
}
Knight.java的代码如下:
package sia.knights;
public interface Knight {
void embarkOnQuest();
}
BraveKnight.java的代码如下:
package sia.knights;
public class BraveKnight implements Knight {
private Quest quest;
public BraveKnight(Quest quest) {
this.quest = quest;
}
public void embarkOnQuest() {
quest.embark();
}
}
主文件KnightMain.java的代码如下:
package sia.knights;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class KnightMain {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("knight.xml");
Knight knight = context.getBean(Knight.class);
knight.embarkOnQuest();
context.close();
}
}
Wiring文件knight.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">
<bean id="knight" class="sia.knights.BraveKnight">
<constructor-arg ref="quest" />
</bean>
<bean id="quest" class="sia.knights.SlayDragonQuest">
<constructor-arg value="#{T(System).out}" />
</bean>
</beans>
2.2 项目的编译和运行
手工编译,需自己撰写编译指令,如下:
javac -d classes src/sia/knights/Quest.java
javac -classpath classes;. -d classes src/sia/knights/SlayDragonQuest.java
javac -d classes src/sia/knights/Knight.java
javac -classpath classes;. -d classes src/sia/knights/BraveKnight.java
javac -classpath lib\spring-core-4.1.1.RELEASE.jar;lib\spring-beans-4.1.1.RELEASE.jar;lib\spring-context-4.1.1.RELEASE.jar;classes;. -d classes src/sia/knights/KnightMain.java
上面编译命令执行后,在classes文件夹内的相应包中会出现class文件。
项目的运行指令如下:
java -classpath lib\spring-expression-4.1.1.RELEASE.jar;lib\commons-logging-1.1.3.jar;lib\spring-core-4.1.1.RELEASE.jar;lib\spring-beans-4.1.1.RELEASE.jar;lib\spring-context-4.1.1.RELEASE.jar;classes;. sia/knights/KnightMain
上面的运行指令所用的jar包比编译时要多。
运行结果如下:
3 总结
本例子是针对普通的Java程序来应用Spring框架,需事先下载相应的Spring jar包。可以看出,Spring框架的代码低侵入特性,实例的自动创建和关联(wiring)。
在编译和运行本项目时,jar包名必须写全名,不能用通配符。
Craig Walls. Spring in Action. 4th Edition. Shelter Island, NY: Manning Publications, 2015, pp7-11. ↩︎