终究还是错付了——最爱的@Autowired产生警告了

77 阅读2分钟

在idea中,当我们使用@Autowired直接修饰需要注入的属性时,可能会报如下图所示的警告:

image.png

虽然以上警告并不影响我们的使用,但作为一个有代码洁癖的码农,看到注解下的波浪线,瞬间感觉整个人都不好了。

image.png

Why?为什么报警告呢?

Spring团队建议: 始终在bean中使用基于构造函数的依赖注入!!!

idea为了我们能写出更优雅的代码,所以就有了警告伺候。哼哼哼,看你改不改!!!

一. 为什么不建议使用@Autowired修饰属性

1. Spring的三种注入方式

  • 基于属性注入
  • 基于setter方法注入
  • 基于构造方法注入

2. 使用@Autowired修饰属性的缺点

当我们使用基于属性的注入时,一般可以直接使用@Autowired注解来修饰属性,省时省力,但这也存在一些缺点:

1). 使用final修饰属性,可以防止值被修改,但@Autowired不能修饰final修饰的属性。

image.png

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修饰的属性,生成对应的构造方法。

怎么样?上面的写法够简洁吧。老铁们,抓紧试一下吧!!!