在idea中,当我们使用@Autowired直接修饰需要注入的属性时,可能会报如下图所示的警告:
虽然以上警告并不影响我们的使用,但作为一个有代码洁癖的码农,看到注解下的波浪线,瞬间感觉整个人都不好了。
Why?为什么报警告呢?
Spring团队建议: 始终在bean中使用基于构造函数的依赖注入!!!
idea为了我们能写出更优雅的代码,所以就有了警告伺候。哼哼哼,看你改不改!!!
一. 为什么不建议使用@Autowired修饰属性
1. Spring的三种注入方式
- 基于属性注入
- 基于setter方法注入
- 基于构造方法注入
2. 使用@Autowired修饰属性的缺点
当我们使用基于属性的注入时,一般可以直接使用@Autowired注解来修饰属性,省时省力,但这也存在一些缺点:
1). 使用final修饰属性,可以防止值被修改,但@Autowired不能修饰final修饰的属性。
2). 会导致程序与容器的紧耦合,如果我们没通过容器创建对象,就无法直接对私有的属性进行赋值。
3). 无法检测到bean循环依赖引起的启动异常。
二. 处理方案
了解了以上这些原因之后,接下来老任就来给大家说说具体的处理方案吧。
1. 使用setter注入
在setter注入时,我们要使用@Autowired注解来修饰setter方法。
package com.qfedu.anno;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
public class UserService {
private UserDao userDao;
@Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void addUser() {
userDao.insert();
}
}
2. 通过构造方法注入
通过构造方法注入,则是Spring团队推荐的注入方式。
package com.qfedu.anno;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
public class UserService {
// 使用final修饰属性,在构造方法中对其进行赋值
private final UserDao userDao;
public UserService(UserDao userDao) {
this.userDao = userDao;
}
public void addUser() {
userDao.insert();
}
}
需要注入的属性,建议使用final进行修饰,这可以防止值被修改,程序更健壮。
3. 结合@RequiredArgsConstructor使用
如果我们需要注入的属性比较多,而对应构造方法的参数比较多,这样看着就会很繁琐,我们可以借助
Lombok的
package com.qfedu.anno;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class UserService {
// 使用final修饰属性
private final UserDao userDao;
public void addUser() {
userDao.insert();
}
}
@RequiredArgsConstructor
注解来写出更简洁的代码。
@RequiredArgsConstructor
用于为final或者@NonNull修饰的属性,生成对应的构造方法。
怎么样?上面的写法够简洁吧。老铁们,抓紧试一下吧!!!