当你看到这篇文章时,我想你也一定是刚刚入门Spring的小伙伴;当然了,也不排除你是Spring大牛,再来回味Spring的神奇。
当你想学习Spring时,你也应该知道Spring这货是什么了!!!简单来说,Spring就是一个牛逼的Java框架,一个致力于简化企业级Java开发,促进代码松散耦合(高内聚,低耦合)的Java开发框架。
而让Spring框架风靡一时,如此流行是基于以下两个关键点:
也就是说,理解,吃透了依赖注入和AOP,也就把握了Spring框架的灵魂和内在了。而这篇Spring学习的开篇文章,我将对Spring的依赖注入进行一个浅尝辄止的学习与总结,后面再用其它文章进行更全面的总结。来吧,伙计~~~
比如,现在有这么个业务场景:
一家公司,有初级工程师和高级工程师两个类别;而一项工作,既可以由初级工程师来完成,也可以由高级工程师来完成;而具体由谁来完成是根据不同的策略来决定的。
现在我们来搞定这个事情,我们可能会这样写代码:
// 工程师接口
public interface Enginner {
String getDescription();
}
// 初级工程师类
public class JuniorEngineer implements Enginner {
@Override
public String getDescription() {
return "I am a junior engineer";
}
}
// 高级工程师类
public class SeniorEngineer implements Enginner {
@Override
public String getDescription() {
return "I am a senior engineer";
}
}
// 工作类
public class Job {
public void doJob(String type) throws Exception {
Enginner enginner;
if (type == "S") {
// 由高级工程师来完成这项工作
enginner = new SeniorEngineer();
} else if (type == "J") {
// 由初级工程师来完成这项工作
enginner = new JuniorEngineer();
} else {
throw new Exception("Wrong Type");
}
// 纯粹的测试代码
System.out.println(enginner.getDescription());
}
}
在我们的程序中,这种代码随处可见,Job
类需要依赖Enginner
接口的实现类,所以,在Job
类内部,就直接进行了new SeniorEngineer()
和new JuniorEngineer()
操作,new
出来的对象则由Job类对象自己亲自管理,这样就无形中增加了代码耦合。
既然代码耦合的问题已经抛出来了,那我们就要解决这个问题,改良后的版本如下:
// 工作类
public class Job {
private Enginner enginner;
public Job(Enginner enginner) {
this.enginner = enginner;
}
public void doJob() throws Exception {
// 纯粹的测试代码
System.out.println(enginner.getDescription());
}
}
// 测试类
public class Test {
public static void main(String []args) {
// 创建JuniorEngineer对象
Enginner enginner = new JuniorEngineer();
// 注入到Job中
Job job = new Job(enginner);
try {
job.doJob();
} catch (Exception e) {
System.out.print(e.getMessage());
}
}
}
这样看起来,代码清爽了很多,在Job
类内部,不再亲自new
对象了,而需要的对象则通过“注入”的方式传递进来。而new
对象的操作,统一放到“最上层”,或者说统一管理new
操作。这就是“依赖注入”的基本概念。当你依赖某个对象时,不再需要你自己亲自去new
这个对象,而是由“外部”将这个对象“注入”到你依赖的地方。
上面我通过一个最简单的例子来说明“依赖注入”是个什么鬼。最终,我们还是需要学习通过Spring框架来完成这件事情,让“依赖注入”变的更简单。
// 测试类
public class Test {
public static void main(String []args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("job.xml");
Job job = context.getBean(Job.class);
try {
job.doJob();
} catch (Exception e) {
System.out.print(e.getMessage());
}
context.close();
}
}
在上述代码中,通过ClassPathXmlApplicationContext
类来加载了一个job.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">
<!-- 创建SeniorEngineer对象 -->
<bean id="seniorengineer" class="com.jellythink.SeniorEngineer" />
<!-- 创建JuniorEngineer对象 -->
<bean id="juniorengineer" class="com.jellythink.JuniorEngineer" />
<bean id="job" class="com.jellythink.Job">
<!-- 将juniorengineer通过构造函数的方式注入到Job对象中 -->
<constructor-arg ref="juniorengineer" />
</bean>
</beans>
结合上面的代码和配置文件来简单的说说Spring是如何工作的。
Spring通过应用上下文(Application Context)装载bean的定义并把它们组装起来。Spring应用上下文全权负责对象的创建和组装。Spring自带了多种应用上下文的实现,它们之间主要的区别仅仅在于如何加载配置。上面的代码中,我没有使用一个new
来创建对象,而对象的创建工作都由Spring来搞定。
在网上看搜索“依赖注入”相关的文章时,都会说到“控制反转”,那么就有人问了,我为什么不说说“控制反转”呢?
其实,对于这些概念性的东西,我还是不想过多的进行解释,说多了,把你绕进去了;说少了,你还搞不明白,那索性就不说了,只要搞清楚了这个概念背后的原理,叫什么都可以的。
如果你非要纠结这个,我就甩给你两个链接:
IOC和DI有什么区别?
谈谈我对Spring IOC与DI的理解
我想上面说的肯定比我说的“好听”。
上面对Spring中的“依赖注入”进行了大概的说明,至少看到这里,你应该知道“依赖注入”是个什么东西,至于上面说的应用上下文、以及配置文件的写法,这些你在这里都不用太多的关注,后面有更多的文章对这些进行详细的总结。
你应该了解Spring的“依赖注入”了吧!!!
当然了,如果你觉的我写的还不错;你可以点击下方的“打赏”按钮支持我哦,你的支持,是我最大的动力。
果冻想-一个原创技术文章分享网站。
2017年5月20日 于呼和浩特。
未经允许不得转载:果冻想 » 初窥Spring之依赖注入