初窥Spring之依赖注入

来源:互联网 发布:数据质量监控系统 编辑:程序博客网 时间:2024/06/09 22:36

简单说说Spring

当你看到这篇文章时,我想你也一定是刚刚入门Spring的小伙伴;当然了,也不排除你是Spring大牛,再来回味Spring的神奇。

当你想学习Spring时,你也应该知道Spring这货是什么了!!!简单来说,Spring就是一个牛逼的Java框架,一个致力于简化企业级Java开发,促进代码松散耦合(高内聚,低耦合)的Java开发框架。

而让Spring框架风靡一时,如此流行是基于以下两个关键点:

  • 依赖注入
  • AOP

也就是说,理解,吃透了依赖注入和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来完成“依赖注入”

上面我通过一个最简单的例子来说明“依赖注入”是个什么鬼。最终,我们还是需要学习通过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中的“依赖注入”进行了大概的说明,至少看到这里,你应该知道“依赖注入”是个什么东西,至于上面说的应用上下文、以及配置文件的写法,这些你在这里都不用太多的关注,后面有更多的文章对这些进行详细的总结。

原创粉丝点击