spring依赖注入(dependency injection)
先说结论
- 实际开发时尽量选择 构造器注入 而不是 字段注入。
- 设值注入 和 方法注入 适用的场景较少,较特殊。
原因
- 官方推荐使用!
- 代码更简洁:配合 lombok 的 @requiredargsconstructor,可以自动生成包含所有 final 字段的构造函数。
- 更安全:构造器注入确保所有必需的依赖在对象创建时就已经注入,避免了在运行时忘记注入某个依赖导致 nullpointerexception 的问题。
- 更易于测试:使用构造器注入时,可以直接通过构造器传递依赖进行单元测试,而不需要模拟框架的注入机制。
至于 @resource它是 java 的 javax.annotation.resource 注解,个人建议在spring项目中就不要用了。
两者区别如下:
@autowired
- spring 提供的注解:@autowired 是 spring 容器提供的注解,专门用于依赖注入。
- 默认按类型注入:@autowired 默认按照类型(type)进行注入。
- 可指定按名称注入:可以通过 @qualifier 注解指定按名称注入。
@resource
- j2ee 标准注解:@resource 是 j2ee 标准的一部分,通常用于 ejb 和其他 j2ee 资源的注入。
- 默认按名称注入:@resource 默认按照名称(name)进行注入,如果找不到匹配的名称,则按类型(type)注入。
- 不需要 @qualifier:@resource 可以通过 name 属性指定名称,而不需要额外的 @qualifier 注解。
一、构造器注入(constructor injection)
构造器注入通过类的构造方法来传递依赖。
举个例子:
@restcontroller @requiredargsconstructor public class warningtaskcontroller { // 注意使用 final 标记不可变 private final warningtaskservice taskservice; // 多个依赖可以 }
二、设值注入(setter injection)
设值注入通过 setter 方法来注入依赖。
举个例子:
使用 spring security ,默认内存用户认证的信息可以配置spring.security.user.name=customusername
就是通过 setter 注入。
源码如下:
@configurationproperties(prefix = "spring.security") public class securityproperties { // 省略一些非必要的代码 private final user user = new user(); public user getuser() { return this.user; } public static class user { private string name = "user"; private string password = uuid.randomuuid().tostring(); private list<string> roles = new arraylist<>(); private boolean passwordgenerated = true; public string getname() { return this.name; } public void setname(string name) { this.name = name; } // 省略其他 getter/setter } }
三、字段注入(field injection)
字段注入直接通过字段来注入依赖。
举个例子:
@restcontroller public class warningtaskcontroller { // 不推荐使用 // 如果依赖非常多,代码会很臃肿 @autowired private final warningtaskservice taskservice; }
四、方法注入(method injection)
方法注入通过方法参数来注入依赖。
举个例子:
@restcontroller public class warningtaskcontroller { private warningtaskservice taskservice; // 不推荐 如果对象是可变的 @autowired public void configure(warningtaskservice taskservice) { this.taskservice = taskservice; } // 其他业务逻辑... }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论