关于@Autowired的使用:推荐使用构造函数进行注入

近期看同事用idea开发的代码,发现在使用@Autowired的时候,大多使用构造函数进行注入。

以前自己在写代码的时候都是直接在变量上进行注入,也没注意过,查了些资料,发现如果直接在变量上进行注入,那么可能会造成NPE。

 

构造函数注入的方式:

public class TestController {

private final TestService testService;

        @Autowired

        public TestController(TestService testService) {

                this.testService = testService;

        }

        …

}

 

变量注入的方式:

public class TestController {

        @Autowired

        private TestService testService;   

           …

 }

 

那么为什么变量注入的方式可能会造成NPE?如下:

public class TestController {

        @Autowired

        private TestService testService;

        private String testname;

                 public TestController(){

                         this.testname = testService.getTestName();

                 }

 }

这段代码执行时会报NPE。

该类的构造函数中的变量值是通过TestService实例来调用TestService类中的方法获得,而Java类会先执行构造函数,然后在通过@Autowired注入实例,因此在执行构造函数的时候就会报错。

 

解决方案就是采用构造函数的注入方式,如下:

public class TestController {

        private TestService testService;

        private String testname;

        @Autowired

         public TestController(TestService testService){

                this.testService = testService;

                this.testname = testService.getTestName();

          }

 }

 

上面的方法中没有加入final来修饰,但是spring官方文档上是建议将成员变量加上final类型的,这是为什么呢?

有网友解释:

1.spring配置默认的bean的scope是singleton,可以通过设置bean的scope属性为prototype来声明该对象为动态创建。但是,如果你的service本身是singleton,注入只执行一次。

2.@Autowired本身就是单例模式,只会在程序启动时执行一次,即使不定义final也不会初始化第二次,所以这个final是没有意义的吧。

无论是spring的bean的scope是单例还是多例,成员变量加上了final后,只能被赋值一次,赋值后值不再改变。

 

注意:

1.如果使用变量注入的话,可能回导致循环依赖,即A里面注入B,B里面又注入A。

2.在代码中发现构造方法中注入了很多依赖,显得很臃肿,对于这个问题,说明类中有太多的责任,违反了类的单一性职责原则,这时候需要考虑使用单一职责原则进行代码重构。

 

参考资料:https://blog.csdn.net/qq_28587263/article/details/75570745

你可能感兴趣的:(Spring学习)