Spring依赖注入理论学习和AOP理论

学习自《Spring实战》

一.Spring的意义以及基本策略

创建Spring的主要目的是:替代重量级的企业级java技术,简化Java的开发过程。

许多框架只能在某些方面做简化,但Spring的目的是全方位的简化,为了实现这个目标,Spring采取了
下面4种简化策略:
1.基于POJO(JavaBean)的轻量级和最小侵入式编程。
2.通过依赖注入和面向接口实现松耦合(易于进行单元测试)。
3.通过切面和惯例进行声明式编程。
4.通过切面和模板减少样板式代码。

Spring做的任何一件事都可以用上面四种策略解释。

耦合具有两面性。一方面,紧密耦合的代码会难以测试,难以复用,难以理解,并且典型地表现出打地鼠式bug,另一方面,一定程度的耦合又是必须的(没有耦合的代码难以完成复杂的功能),为了完成有实际意义的功能,不同的类必须以适当的方式进行交互。(松耦合)

二.依赖注入(DI)

1.DI功能是如何实现的?

我们知道任何一个有实际意义的类的应用都会由两个或更多的类组成,这些类相互协助来完成特定的业务逻辑,按照传统的说法就是每个对象负责管理与自己相互协助的对象(所依赖的对象)的引用,很明显这会造成连锁反应,难以进行测试。

理论有点抽象?我们来看看下面的例子吧!

public class DamselRescuingKnight implements Knight{
  private RescueDamselQuest quest;

  public DamselRescuingKnight()
  {
    this.quest=new RescueDamselQuest();
  }
  public void embarkOnQuest()
  { 
   quest.embark();
  }

通过上面代码我们知道DamselRescuingKnight和RescuDamselQuest之间紧耦合。
也就是说,只有RescuDamselQuest类的embark()不存在bug时,上面的类对象才可以顺利创建和使用。那意味着如果我们要测试此类的话,就必须保证这个类中所引用的类必须无错误,这就导致我们单纯地编写针对这个类的单元测试显得很困难。

如何解决上面的问题呢?
这时候依赖注入的作用就体现出来了。
我们知道产生紧耦合的原因是多个功能类之间的关联太紧密,那么我们有没有什么方法使它们之间的关系变的松一点呢?答案是引入一个接口来作为一个桥梁实现松关联。
我们看看下面代码:

public class BraveKnight implements Knight{
    private Quest quest;
    public BraveKnight(Quest quest)//Quest被注入进来
    {
        this.quest=quest;
    }
    public void embarkOnQuest()
    {
        quest.embark();
    }
}

其中Quest是一个接口,其中定义了多个任务类。具体的任务类通过实现这个接口用接口回调与BraveKnight产生联系,但BraveKnight又不依赖于具体的任务类。这使得我们的测试代码变得容易许多:

 public static void main(String[] args) {

        Quest quest=new Quest(){
            @Override
            public void embark() {
                System.out.println("无需连锁");
            }
        };

        BraveKnight a=new BraveKnight(quest);

        a.embarkOnQuest();

    }

简答来说依赖注入就是实现松耦合的一种方式。

三.什么是AOP

我们知道DI可以让项目协作的组件保持松耦合,而AOP允许我们把遍布应用各处的功能分离出来形成可重用的组件。

一.为何要这样做?
我们知道系统由许多不同的组件组成,每一个组件负责一块特定的功能,但除了实现自身的核心功能之外,它们还经常承担着额外的职责(比如日志,事务管理和安全这样的系统服务经常融入到自身具有核心业务逻辑的组件中去)这些系统服务通常称为横切关注点,因为它们会跨越系统的多个组件。
如果将这些关注点分散到多个组件中去,我们会发现我们的代码将会有双重复杂性:

1.实现系统关注点功能的代码将会重复出现在多个组件中。这就意味着如果你要改变这些关注点的逻辑,就必须修改各个模块中的相关实现,即使我们把这些关注点抽象为一个独立的模块,其他模块只是调用它的方法,但方法的调用还是会出现各个模块中(即使代码量很少)。

2.组件会因为那些与自身核心业务无关的代码而变得混乱。
下面的图可以直观了解:
在这里插入图片描述
AOP可以让这些服务模块化,并以声明的方式将它们应用到它们需要影响的组件中去。组件无需编写其他代码来实现服务

猜你喜欢

转载自blog.csdn.net/c1776167012/article/details/106248659
今日推荐