Spring依赖注入与控制反转

文章目录

  • DI和IOC
  • 依赖注入的三种方式
  • `@Resource` 和 `@Autowired`
      • @Resource 注解:
      • @Autowired 注解:
      • 选择使用:

DI和IOC

依赖注入(DI)和控制反转(IoC)是关联的概念,通常在软件设计和开发中一起使用。它们都旨在降低组件之间的耦合度,并提高代码的可维护性和可测试性。

  1. 控制反转(IoC)

    • 控制反转是一种设计原则,它反转了传统的程序设计思想,将应用程序的控制权从程序本身转移到了外部容器(通常是框架或容器)中。
    • 在传统的程序设计中,应用程序自己负责控制和管理其组件的生命周期和依赖关系。而在IoC中,这些控制权被反转,交给了外部容器。
    • 通过IoC,开发人员不需要直接管理对象的创建和依赖关系,而是由容器来完成。这种反转控制的方式可以提高代码的灵活性和可扩展性。
  2. 依赖注入(DI)

    • 依赖注入是IoC的一种具体实现方式,是指组件的依赖关系由外部容器在组件被创建时注入。
    • 在依赖注入中,对象不再负责创建或查找依赖的对象,而是由外部容器负责。这样可以通过构造函数、方法参数、或者属性注入来实现。
    • 依赖注入有助于解耦组件,使得它们更容易测试和维护,同时也使得组件的替换和升级变得更为简单。

IoC是一种更宽泛的概念,它强调控制的反转,而依赖注入是IoC的一种具体实现方式,强调通过注入的方式管理组件之间的依赖关系。在实际应用中,常常会看到这两个概念一起出现,以实现更松散耦合、可维护和可测试的代码结构。Spring框架是一个典型的IoC容器,它广泛使用了依赖注入来管理组件之间的依赖关系。

依赖注入的三种方式

  1. 构造函数注入(Constructor Injection)

    • 在这种方式中,依赖通过类的构造函数进行注入。
    • 优点:依赖关系在对象创建时就被明确地传递,使得对象在创建后就是完全初始化的。
    • 缺点:在构造函数的参数列表中可能会变得很长,特别是当依赖关系较多时,这可能导致代码可读性降低。
    public class MyClass {
        private MyDependency dependency;
    
        public MyClass(MyDependency dependency) {
            this.dependency = dependency;
        }
    
        // 其他类成员和方法...
    }
    
  2. 设值注入(Setter Injection)

    • 在这种方式中,依赖通过类的setter方法进行注入。
    • 优点:相对于构造函数注入,参数列表不会很长,且可以在对象创建后随时更改依赖。
    • 缺点:对象可能在依赖注入之前处于部分初始化的状态。
    public class MyClass {
        private MyDependency dependency;
    
        public void setDependency(MyDependency dependency) {
            this.dependency = dependency;
        }
    
        // 其他类成员和方法...
    }
    
  3. 接口注入(Interface Injection)

    • 在这种方式中,通过在类中定义一个接口,类实现该接口并在接口方法中接收依赖。
    • 优点:相对较少使用,通常不被推荐,因为这种方式破坏了对象的封装性。
    • 缺点:将依赖注入的责任交给了使用者,增加了实现类的复杂性,使得代码更难维护。
    public interface MyInterface {
        void setDependency(MyDependency dependency);
    }
    
    public class MyClass implements MyInterface {
        private MyDependency dependency;
    
        @Override
        public void setDependency(MyDependency dependency) {
            this.dependency = dependency;
        }
    
        // 其他类成员和方法...
    }
    

在实际应用中,常常会结合使用这些方式,选择适合项目需求的方式来实现依赖注入。例如,使用构造函数注入来保证对象在创建时依赖完全初始化,同时结合设值注入来允许在运行时更改依赖。

@Resource@Autowired

@Resource@Autowired 是 Java 中用于进行依赖注入的两个常用注解,通常在使用 Spring 框架时经常见到它们。它们都用于自动装配,但在一些细节和用法上存在一些差异。

@Resource 注解:

  1. 来源@Resource 是 Java EE 提供的注解,包含在 javax.annotation 包中,不是 Spring 特有的注解。

  2. 装配规则:通过名称装配,默认通过组件名称(即成员变量名)进行匹配。如果指定了 name 属性,则使用指定的名称进行匹配。

  3. 支持类型@Resource 可以用于字段、方法和构造函数上,但不支持 @Primary@Qualifier

  4. 可选属性

    • name:指定要注入的组件名称。
    • type:指定要注入的组件类型。

示例:

@Resource(name = "myBean")
private MyBean myBean;

@Autowired 注解:

  1. 来源@Autowired 是 Spring 提供的注解,包含在 org.springframework.beans.factory.annotation 包中。

  2. 装配规则:通过类型装配,默认通过类型匹配。如果多个类型匹配,可以结合 @Qualifier 使用,或者使用 @Primary 指定首选注入的 bean。

  3. 支持类型@Autowired 可以用于字段、方法和构造函数上,支持 @Primary@Qualifier

  4. 可选属性

    • required:指定是否必须要有一个匹配的 bean。默认为 true,表示必须有匹配的 bean;如果设置为 false,表示可以没有匹配的 bean。

示例:

@Autowired
@Qualifier("myBean")
private MyBean myBean;

选择使用:

  • 如果项目中使用了 Spring 框架,通常推荐使用 @Autowired,因为它提供了更多的功能和灵活性。
  • 如果希望使用 Java EE 规范,或者在非 Spring 环境中,可以使用 @Resource
  • 在某些场景下,两者也可以结合使用。

需要注意的是,虽然 @Resource@Autowired 都可以用于进行依赖注入,但在实际使用中,根据具体的场景和需求,选择合适的注解可以使代码更为清晰和灵活。

你可能感兴趣的:(spring,rpc,java)