Spring中被放弃的@Autowired,你会用吗?

2024年 3月 6日 97.3k 0

注入方式一:属性(字段)注入

在某个属性(字段)上使用@Autowired注解时,Spring在创建该Bean的过程中,会根据字段的类型或名称从Spring容器中查找到所匹配的Bean对象,并赋值给该熟悉。

@Service
public class UserService {

    // 注入方式一:属性注入
    @Autowired
    private RoleService roleService;

    public void printRoleService() {
        System.out.println(roleService);
    }

}

注入方式二:Setter注入

在某个Setter方法上使用@Autowired注解时,Spring在创建该Bean的过程中,会来调用该Setter方法,并且如果Set方法有入参参数,那么Spring会格局入参参数信息,从Spring容器中找到所匹配的Bean对象赋值给该入参。我们通过再Setter方法中给属性赋值,从而就达到了Setter方法注入的目的。

@Service
public class UserService {

    private RoleService roleService;

    public void printRoleService() {
        System.out.println(roleService);
    }

    public RoleService getRoleService() {
        return roleService;
    }

    // 注入方式二:Setter注入
    @Autowired
    public void setRoleService(RoleService roleService) {
        this.roleService = roleService;
    }
}

注意:@Autowired注解其实可以添加在任何一个普通方法上,不一定是Setter方法。

注入方式三:构造函数注入

当某个构造方法上使用@Autowired注解时,表示该Bean在创建时会使用这个构造方法来实例化得到一个对象,并且Spring会根据该构造函数的入参参数的类型和名字,从Spring容器中找到所匹配的Bean对象传给该入参,通过在构造函数中给属性赋值,从而就达到了构造函数注入的目的。

@Service
public class UserService {

    private RoleService roleService;

    // 注入方式三:构造函数注入
    @Autowired
    public UserService(RoleService roleService) {
        this.roleService = roleService;
    }

    public void printRoleService() {
        System.out.println(roleService);
    }
}

注入方式四:参数注入

尽管@Autowired注解可以加在普通方法或构造方法的参数之前,但是Spring框架中大部分地方都忽略了这种情况下的@Autowired注解,仅仅在spring-test模块中的对于JUnit Jupiter的支持中,支持了参数前添加@Autowired。

@SpringBootTest(classes = ConstructorAttributeMain.class)
class UserServiceTest {

    @Test
    void printRoleService(@Autowired UserService userService) {
        userService.printRoleService();
    }
}

required属性释义

  • required=true:默认值,必须存在Bean,否则报错
  • required=false:若找不到Bean,则为空
@Service
public class UserService {

    @Autowired(required = true)
    private RoleService roleService;

    @Autowired(required = false)
    private MenuService menuService;

    public void print() {
        System.out.println("role: " + roleService); // print class
        System.out.println("menu: " + menuService); // pint null
    }
}

静态属性(字段)注入

静态属性(字段)或方法是不会进行依赖注入的。

@Service
public class UserService {

    @Autowired
    private static RoleService roleService;


    public void printRole() {
        System.out.println(roleService);
    }
}

但是实际开发中,我们可能会遇到此问题。因此,有两种方式解决此问题:

构造方法注入

@Service
public class UserService {

    private static RoleService roleService;

  // 解决静态导入第一种方式:构造函数注入
    @Autowired
    public UserService(RoleService roleService) {
        UserService.roleService = roleService;
    }

    public void printRole() {
        System.out.println(roleService);
    }
}

Setter方法注入

@Service
public class UserService {

    private static RoleService roleService;

    // 解决静态导入第二种方式:Setter方法注入
    @Autowired
    public void setRoleService(RoleService roleService) {
        UserService.roleService = roleService;
    }

    public void printRole() {
        System.out.println(roleService);
    }
}

小结

综上所述,@Autowired有三种注入方式,分别为:字段(属性)注入,构造函数注入和Setter方法注入。

另外,@Autowired参数注入,仅在单元测试才有意义;静态字段(属性)注入为空问题,需要结合构造函数或Setter方法注入。

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论