目标
- 绝对不使用字段注入
- 绝对不多写一行多余代码
- 绝对不少写一行必要代码
项目文件

使用字段注入
@RestController
@RequestMapping("/users")
public class UserController {
// 此处 idea会有黄色的警告,因为使用了字段注入
@Autowired
private UserService userService;
@GetMapping({"{userId}"})
public User me(@PathVariable String userId) {
final User user = userService.findById(userId);
if (user == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "未找到"+userId);
}
return user;
}
}
使用构造器注入
@RestController
@RequestMapping("/users")
public class UserController {
private final UserService userService;
// spring4.3之后如果一个类只有一个构造器,可不加任何注入相关注解
//@Autowired
public UserController(UserService userService) {
this.userService = userservice;
}
@GetMapping({"{userId}"})
public User me(@PathVariable String userId) {
final User user = userService.findById(userId);
if (user == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "未找到"+userId);
}
return user;
}
}
使用@RequiredArgsConstructor注入必须依赖
@RestController
@RequestMapping("/users")
@RequiredArgsConstructor //会自动生成一个所有final字段的构造函数
public class UserController {
//建议所有必须依赖都加final
private final UserService userService;
@GetMapping({"{userId}"})
public User me(@PathVariable String userId) {
final User user = userService.findById(userId);
if (user == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "未找到"+userId);
}
return user;
}
}
使用@FieldDefaults添加字段修饰符
@RestController
@RequestMapping("/users")
@RequiredArgsConstructor //会自动生成一个所有final字段的构造函数
@FieldDefaults(makeFinal = true, // 设置所有字段为final
level = AccessLevel.PRIVATE) // 设置所有字段为private
public class UserController {
//建议所有必须依赖都加final
UserService userService;
@GetMapping({"{userId}"})
public User me(@PathVariable String userId) {
final User user = userService.findById(userId);
if (user == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "未找到"+userId);
}
return user;
}
}
利用@Setter @Nullable和@NonFinal注入可选依赖
@RestController
@RequestMapping("/users")
@RequiredArgsConstructor
@Slf4j
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
public class UserController {
UserService userService;
// 这个注解是spring5.0之后加入和注解
@Nullable
@NotBlank
@NonFinal // 排除@FieldDefaults设置的fianl修饰符
//在 setSmsSender方法上生命@Autowired}
@Setter(onMethod_ = {@Autowired
// 这个可加可不加,详见生成后文件(required = false)
})
SmsSender smsSender;
@GetMapping({"{userId}"})
public User me(@PathVariable String userId) {
final User user = userService.findById(userId);
if (user == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "未找到" + userId);
}
return user;
}
@PostMapping("sms-send")
public void sendSms(@RequestParam String phone, @RequestParam String content) {
sendSmsIfAvailable(phone, content);
}
private void sendSmsIfAvailable(String phone, String content) {
if (smsSender != null) {
smsSender.sender(phone, content);
} else {
log.info("向手机号:{} 发送内容:{}", phone, content);
}
}
}
最终生成的文件
import cn.len.article.spring01.domain.User;
import cn.len.article.spring01.service.UserService;
import cn.len.article.spring01.vendor.SmsSender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;
import javax.validation.constraints.NotBlank;
@RestController
@RequestMapping({"/users"})
public class UserController {
private static final Logger log = LoggerFactory.getLogger(UserController.class);
// 非静态字段加上了private和final修饰符
private final UserService userService;
@Nullable
@NotBlank
private SmsSender smsSender;
@GetMapping({"{userId}"})
public User me(@PathVariable String userId) {
User user = this.userService.findById(userId);
if (user == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "未找到" + userId);
} else {
return user;
}
}
@PostMapping({"sms-send"})
public void sendSms(@RequestParam String phone, @RequestParam String content) {
this.sendSmsIfAvailable(phone, content);
}
private void sendSmsIfAvailable(String phone, String content) {
if (this.smsSender != null) {
this.smsSender.sender(phone, content);
} else {
log.info("向手机号:{} 发送内容:{}", phone, content);
}
}
// 由lombok的@RequiredArgsConstructor生成的唯一构造器
public UserController(final UserService userService) {
this.userService = userService;
}
@Autowired
// 在spring5.0之后被Optional 或@Nullable作用的参数注入是可选的
// 我们并没有在上面的@Setter在参数上声明任何注解,但是处理过的文件却有@Nullable这个注解
// 可能是因为放在字段上的@Nullable上面注解了jsr305的 @Nonnull注解,lombok做了特殊处理
// jsr validator的@NotBlank注解并没有出现在参数里面
public void setSmsSender(@Nullable final SmsSender smsSender) {
this.smsSender = smsSender;
}
}
测试
发送短信,非production环境



发送短信,production环境


最终生成类

网友评论