Are you still using @Autowired and @Resource?

I am participating in the "Nuggets · Sailing Program"

First of all, I do not admit that my title is suspected of being false, exaggerated and draining, and I will go straight to the topic.

First through the bottom: 我们在类上使用 Lombok的@RequiredArgsConstructor 注解来替代类中的多处@Autowired和@Resource.

dependency injection

Let's review the three types of dependency injection in Spring.

  1. property injection
public class SysUserController extends BaseController {
    @Autowired
    private ISysUserService userService;

    @Resource
    private ISysRoleService roleService;
}
复制代码

@Autowired is assembled by type by default, and @Resource is assembled by name by default. When no bean matching the name is found, it will be assembled by type.

And @Qualifier is used in conjunction with Autowired to specify the name of the bean, and it can also be assembled by name.

Using @Autowired directly on a variable in IDEA will find a warning: Field injection is not recommended.

The reason is that it is officially recommended that we use the constructor injection method, which has obvious drawbacks, such as: the injected object cannot be modified with final, and the existence of NullPointException cannot be found.

  1. Constructor injection
public class SysUserController extends BaseController {

    private final ISysUserService userService;

    private final ISysRoleService roleService;

    public SysUserController(ISysUserService userService, ISysRoleService roleService) {
        this.userService = userService;
        this.roleService = roleService;
    }
}
复制代码

Constructor dependency injection is implemented by the container triggering the constructor of a class, by forcing the specified dependency injection to ensure the operation of the class, preventing NullPointerException;

Spring officially recommends the use of constructor injection not only because member properties can be modified with the final keyword in this case, but more importantly, it can avoid circular dependencies. If there are circular dependencies, an error will be reported when the Spring project starts.

Why avoid rather than solve it?

因为构造器注入是通过构造方法来生成对象,其必须要先获取属性,才能生成调用构造方法进行实例化,这种情况的循环依赖是无法解决的。

Let's take a picture to see whether Spring can solve the circular dependency when the two interdependent object injection methods of A and B are different:

Constructor injection to solve circular dependencies:
1. Code refactoring
2. @Lazy annotation
3. Use property injection instead
Suggested viewing: zhuanlan.zhihu.com

  1. Setter injection
public class SysUserController extends BaseController {
    
    private ISysUserService userService;

    @Autowired
    public void setUserService(ISysUserService userService) {
        this.userService = userService;
    }
}
复制代码

@AutowiredIt should be noted that you need to add or @Resourceannotate when using Setter injection , otherwise the injection will not be successful.

Another thing to note is that neither property injection nor Setter injected variables can be finalmodified with keywords.

@RequiredArgsConstructor

这里可能会有人说不推荐使用Lombok,只要我们知其然且知其所以然,那他就是一个帮助我们快速开发的好工具。

在说完Spring的三种依赖注入后,我们来认识一下Lombok的@RequiredArgsConstructor 注解。

在Lombok中,生成构造方法的注解一共有三个,分别是@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsContructor,我们这里只介绍@RequiredArgsConstructor。

@Controller
@RequiredArgsConstructor
public class SysUserController extends BaseController {

    private final ISysUserService userService;

    private ISysRoleService roleService;

   //----------------------------
}
复制代码

使用@RequiredArgsConstructor会为我们生成一个包含常量、使用final关键字修饰的变量私有构造方法

那我们就可以不使用属性注入(@Autowired和@Resource)的方式,直接通过构造器的方式来完成注入,不仅能够省略简化许多代码,也解决了属性注入可能存在的空指针问题。

Guess you like

Origin juejin.im/post/7146035741234036744