Spring依赖注入之构造方法注入、set方法注入以及基于字段的方式注入比较

1、spring提供了三种依赖注入的方式,先来看一下各个注入方式的实现方法以及各自的优缺点

1)基于字段注入的方式

  该方式使用@Autowired方法就可以实现类的注入

@Component
public class ClassB {

    @Autowired
    private ClassA classA;

    public void testMethod1() {
        classA.method1();
    }
}

这种注入方式的优点就是实现简单,通过一个注解就可以完成注入。但是这样的弊端却有很多,是最不推荐的一种注入方式。

  1. 当ClassA没有被Spring管理时,则通过@Autowrite注解注入的ClassA则是null,此时调用A的方法会出现空指针异常。而且脱离了容器环境就不能够使用独立的使用ClassB中的ClassA对象,比如代码段:
    ClassB classB = new ClassB();
    classB.classA.method1();
    调用该代码就会出现空指针异常,这样就使得跟Spring框架强行绑定了,脱离框架无法使得代码正确运行
  2.  无法注入一个final类型的属性,这是由于final类型的字段必须在类实例化的时候进行实例化,而Spring的属性注入是在实例化完成之后通过AbstractAutowireCapableBeanFactory#populateBean方法进行属性填充的
    Spring依赖注入之构造方法注入、set方法注入以及基于字段的方式注入比较_第1张图片
  3. 第三点也是最容易忽略的一点,在存在循环依赖问题时,通过@Autowrite方式进行注入时,项目编译不会报错,但是调用循环依赖的方法时则会报错。所以@Autowrite方式不是解决了循环依赖的问题而是将问题隐藏了,这样更致命。 Spring依赖注入之构造方法注入、set方法注入以及基于字段的方式注入比较_第2张图片

 2)基于构造方法的方式进行注入

@Component
public class ClassB {

    private final ClassA classA;

    @Autowired
    public ClassB(ClassA classA) {
        this.classA = classA;
    }

    public void testMethod1() {
        classA.method1();
    }
}

通过对比上一种方法的缺点,我们看一下通过构造方法注入的优点。

  1. 通过构造方法注入可以脱离Spring框架使用注入的类,下面那段代码不会报空指针异常
    ClassB classB = new ClassB(new ClassA());
    classB.testMethod1();
  2.  可以注入final类型的属性,并且能够保证注入的属性都不为空
  3. 如果出现循环依赖的情况,通过该构造方法注入的方式注入的时候编译期间就会报异常
  4. 缺点就是如果注入的类比较多,或者有的类不是强制需要的时候就会增加构造方法的复杂度

3)set方法注入

@Component
public class ClassB {

    private ClassA classA;

    @Autowired
    public void setClassA(ClassA classA) {
        this.classA = classA;
    }

    public void testMethod1() {
        classA.method1();
    }
}
  1. 通过set方法进行注入的时候可以对依赖进行按需注入,避免了构造方法注入的时候许多依赖注入时候的问题
  2. set方法注入可以多次重复注入
  3. set方法注入不会发生循环依赖问题

你可能感兴趣的:(Spring,spring,java,后端)