@Autowired
来源:5-12 【实战应用】用户账户服务功能实现

abel_星123
2019-01-30
``老师我想问下,为什么不直接在注释下面写dao层接口,加final和构造函数的作用是什么?
@Autowired
private AdUserRepository adUserRepository;
private final AdUserRepository adUserRepository;
@Autowired
public UserServiceImpl(AdUserRepository adUserRepository) {
this.adUserRepository = adUserRepository;
}
1回答
-
同学你好:
我暂且把你这里说的两种注入方式叫做第一种和第二种。
对于第一种注入方式,你写完之后,会发现编辑器会给出类似下面的警告信息:
Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies
这里翻译过来的意思是:Spring 建议总是在您的 Bean 中使用构造函数建立依赖注入。总是使用断言强制依赖。(也就是你看到的第二种注入方式)
那么,通过构造函数注入(第二种),有什么好处呢?再来看看 Spring 的文档:
The Spring team generally advocates constructor injection as it enables one to implement application components as immutable objects and to ensure that required dependencies are not null. Furthermore constructor-injected components are always returned to client (calling) code in a fully initialized state.
翻译过来的意思是:这个构造器注入的方式,能够保证注入的组件不可变,并且确保需要的依赖不为空。此外,构造器注入的依赖总是能够在返回客户端(组件)代码的时候保证完全初始化的状态。
解释如下:
1. 依赖不可变:其实说的就是final关键字,Java 的语法。
2. 依赖不为空(省去了我们对其检查):由于自己实现了有参数的构造函数,所以不会调用默认构造函数,那么就需要 Spring 容器传入所需要的参数,所以就两种情况:1、有该类型的参数->传入;2:无该类型的参数->报错。所以保证不会为空。
3. 完全初始化的状态:这个可以跟上面的依赖不为空结合起来,向构造器传参之前,要确保注入的内容不为空,那么肯定要调用依赖组件的构造方法完成实例化。而在Java类加载实例化的过程中,构造方法是最后一步(之前如果有父类先初始化父类,然后自己的成员变量,最后才是构造方法。)。所以返回来的都是初始化之后的状态。
欢迎来 QQ 群随时交流、讨论,也非常感谢同学的支持!
1012019-01-31
相似问题