尊敬的面试官,我该如何告诉你我精通Spring(一)初入Spring

1 写在前面的话

1、小七不提供任何可以直接运行的源代码,好记性不如烂笔头,希望大家可以亲自动手跟着文章中的代码敲一下。
2、本系列文章说的 Spring,未做特殊说明皆指代 SpringFramework。
3、为了更好的阅读本文,读者至少要学习了解过JavaSE和JavaEE。

2 为什么要学 Spring

2.1 从面包来说

SpringFramework 实际上已经成为了 JavaEE 的标准,作为一个后台 JavaCoder 是肯定离不开它的。说直白点就是,企业需要,学习 Spring 能让你升职加薪。

2.2 从精神食粮来说

Spring 无论是设计还是代码规范都很好(如果你有幸拜读过 eureka 的源码,小七相信你一定不会反对我的),对开发人员技术的提升很有帮助。说直白点,多看大佬写的代码,你会感觉自己也是个大佬~

3 如果没有 Spring,我们是怎么写代码

首先我们来看下面这个例子。
假设我们有两个类
类 A

public class A {

    public void a(){
        System.out.println("类 A 的 a()方法被调用了...");
    }

}

类 B

public class B {

    public void b(){
        System.out.println("类 B 的 b()方法被调用了...");
    }

}

如果我们要在 B 类的 b 方法中调用 A 类的 a 方法(这个时候,我们说B是依赖于A的),我们能怎么做呢?

3.1 方案一

直接在 b 方法中,创建 A 对象,通过 A 对象调用 a 方法

public class B {
    public void b(){
        System.out.println("类 B 的 b()方法被调用了...");
        A a = new A();
        a.a();
    }
}

此方案缺点很明显,A和B是强耦合在一起的,并且还是直接写死在b()方法中的。

3.2 方案二

我们通过组合的方式,将A作为B的属性,并且构造B的时候就实例化一个A类。

public class B {
    private A a;

    public B(){
        this.a = new A();
    }

    public void b(){
        System.out.println("类 B 的 b()方法被调用了...");
        this.a.a();
    }
}

以上方案也有缺点。B中A对象的创建是写死的,也就是我们无法控制A对象的生成,举个例子,如果我们想在创建B对象的时候,使用不同的A对象,以上方法就是无能为力的。

3.3 方案三

为了不把B中A对象的创建写死,我们可以改变B的构造方法,外部传A进去。

public class B {
    private A a;

    public B(A a){
        this.a = a;
    }
    
    public void b(){
        System.out.println("类 B 的 b()方法被调用了...");
        this.a.a();
    }
}

这个时候,当前需求下我们的问题基本上都解决了。但是如果B中不仅仅依赖了A,还有CDF等等复杂的依赖关系,且不说写起来复杂,修改、拓展也很困难。

3.4 方案四

以上三种方案都在生成对象的时候存在问题,站在前人的肩膀上,生成对象我们可以使用工厂模式,如下:

public class BeanFactory {
    public static A getBean(String className) {
        try {
            return (A) Class.forName(className).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("初始化失败, 失败原因: " + e.getMessage());
        }
    }
}

这里我们通过反射,传入全类名去获取我们需要的对象,那我们通过BeanFactory.getBean(className)方法,就能很简单的获取到我们想要的那个对象了。

3.5 方案五

针对方案四,我们还可以做一丢丢优化,从外部配置文件获取。
首先在resources下面写一个spring.properties,内容如下

a=com.sheep.ioc.ioc001.A

然后初始化的时候加载这个文件,最后修改一下反射的代码

public class BeanFactory {
    // 直接使用java的类库
    private static Properties properties;

    // 加载spring.properties文件
    static {
        properties = new Properties();
        try {
            properties.load(BeanFactory.class.getClassLoader().getResourceAsStream("spring.properties"));
        } catch (IOException e) {
            throw new ExceptionInInitializerError("BeanFactory初始化失败, 失败原因: " + e.getMessage());
        }
    }

    public static Object getBean(String beanName) {
        try {
            Class<?> beanClazz = Class.forName(properties.getProperty(beanName));
            return beanClazz.newInstance();
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("未获取到[" + beanName + "]的bean!", e);
        } catch (IllegalAccessException | InstantiationException e) {
            throw new RuntimeException("[" + beanName + "]初始化失败!", e);
        }
    }
}

3.6 小结

方案四、五,我们将获取对象的方式交给了 BeanFactory 。这种将控制权交给别人的思想,就叫做:控制反转(IOC)。而 BeanFactory 根据指定的 beanName 去获取和创建对象的过程,就叫做:依赖查找( DL )。 说直白点,就是你去洗脚,平常你随便点一个小姐姐,那么控制权在你;但是有一天你对老板说,你安排,那么控制权就不在你了,你就把点小姐姐的权利给了老板,那么就是控制反转了。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

第七人格

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值