Spring学习笔记(二)——基础篇

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Mr_Megamind/article/details/80932790

前提

这篇博文是这套Spring学习笔记的第二篇——基础篇,主要内容是在开始学习Spring之前需要了解的基础知识。如果需要了解有关Spring的综述信息或博文的索引信息,请移步:
《综述篇》


IoC

IoC是Inverse of Control的缩写,即控制反转。它是Spring容器的内核,AOP、声明式事务等功能的基础,其中涉及对代码解耦、设计模式、代码优化等问题的考量。但IoC这个重要的概念比较晦涩,不容易理解,使得IoC难以实现,因此工业界进行了广泛的讨论。
2004年,国际著名的面向对象分析设计专家Martin Fowler就提出了“哪些方面的控制被反转了?”这个问题。他总结出是依赖对象的获得被反转了,因为大多数应用程序都是由两个或是更多的类通过彼此的合作来实现业务逻辑,这使得每个对象都需要获取与其合作的对象(也就是它所依赖的对象)的引用。如果这个获取过程要靠自身实现,那么这将导致代码高度耦合并且难以维护和调试。[1]
最终,Martin Fowler提出了DI(Dependency Injection:依赖注入),即让调用类对被调用类的依赖关系由第三方(如Spring容器)注入,以消除调用类对被调用类的依赖。这个名词显然比“控制反转”更为明了,也为IoC的实现指明了方向。

一般情况下,假定有两个类A和B,当B类的实现需要依赖A类的对象作为其成员,B类的代码形如:

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

使用了Spring的依赖注入,上述代码中B类的实现即可变为:

public class B{
    @Autowired
    A a;
    ......
}

可以看出,在B类的实现中,对A类的对象引用已经不需要在B类中手动实现,实现了A、B两个类的解耦合。B类中a对象并非没有指向一个A类的实例,其引用是Spring容器根据@Autowired注解自动创建的。关于“@Autowired注解”及其作用将会在后面的博文中讲解。


反射

俗话说“反射反射,程序员的快乐!”
想必大家看完IoC的部分,还是会留下一个小的疑惑,Spring中的DI又是怎么实现的?其实,DI就是通过反射技术实现的。
关于反射我来举一个例子,假设我们需要写一个工厂函数,这个工厂函数通过传入的产品类型"type"字符串来生产客户指定的产品,那么它的代码应该形如:

    public Product factory(String type) {
        Product product;
        switch (type) {
            case "ProductA":
                product = new ProductA();
                break;
            case "ProductB":
                product = new ProductB();
                break;
            ......
            default:
                product = new Product();
                break;
        }
        return product;
    }

可以想象,当具体的产品数量有十个甚至一百个时,这个switch—case结构将会非常的长,但是为了实现功能,还不能进行拆分或者省略。

那么这时,我们假定一个理想化的函数是这样的:

    public Product factory(String type) {
        Function concreteProductConstructor = type.toFunction();
        Product product = concreteProductConstructor.newInstance();
        return product;
    }

因为这里的type字符串是某个产品类的名称,也即是该类构造函数的名称,因此我们希望能有一个函数(这个函数中也不存在switch-case结构),它能把字符串变成相应名称的函数。然后我们通过调用这个函数就能生产客户指定的产品。

**反射技术就可以实现这样的功能,它可以通过指定的字符串去.class文件中找与字符串名称相对应的字段、函数,使程序员可以任意调用它们。**真实的实现上述factory方法以消除switch-case结构的代码大概需要五六行,上面的虚构代码只是为了便于说明,如果需要详细了解反射技术,请移步Java反射机制及IoC原理这边博文,其中的“五.IoC原理”中有真实的代码演示,只不过作者将switch-case结构换做多个并列的if了。


注解

说到注解这个词,可能大家会比较陌生,但其实在日常编写Java代码时,我们就经常遇到一个注解——@Override注解,记起来了吗?Override即重写、覆盖,可以说它是面向对象的编程中,继承的重要组成部分。被冠以@Override的函数均继承自父类并由子类重新实现其功能。如果没有覆盖,子类和父类就是一样的,继承就没有意义了。

对于注解的定义,我的比较通俗的理解是:注解就是给字段或者函数加上一个标签,之后,程序可以根据不同的注解,对这些字段或函数进行与注解相对应的操作。比如前面的“@Autowired”注解,他的意思是自动装配,显而易见,它的作用就是自动装配被冠以该注解的对象,为其自动注入实例引用。

原理上,注解技术也是通过反射技术实现的,如果需要详细了解注解技术,请移步Java利用反射实现注解简单功能这篇博文。


AOP

AOP是Aspect Oriented Programing的缩写,即面向切面的编程。 以下是百度百科的解释:

通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。[2]

关于AOP,目前只能通过文字定义了解到这么多,有关它的知识及代码部分都会在后面用专门的篇幅来讲。


Bean

Bean这个基础概念相当重要,比较官方的解释是:Spring中的Bean,是通过配置文件、Java Config等的设置,由Spring自动实例化,用完后自动销毁的对象。


后记

基础篇目前只想到这些知识,之后的填充还是看我能想到什么或者看大家的反馈中有什么不懂的知识。


  1. 摘自百度百科——依赖注入#起源 ↩︎

  2. 摘自百度百科——AOP ↩︎

猜你喜欢

转载自blog.csdn.net/Mr_Megamind/article/details/80932790
今日推荐