java 构造器注入指定名称的bean spring构造器注入优点_初始化


常用的注入方式

1.使用@Autowired,@Resource等注解自动注入,最为常见

1.注入方式非常简单,只需要加入需要注入的字段,附上该注解就完成

2.整体代码代码简洁明了

但是对于IOC容器以外的环境,除了使用反射提供需要的依赖之外,无法复用该实现类。并且使用field注入可能会导致循环依赖。

2.构造器注入


@Controller
public class UserController {

    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }
}


相较于field注入,显得难看,臃肿,特别是注入的依赖很多的时候。

但是官方推荐还是有很多好处的。

3.setter注入


@Controller
public class UserController {

    private UserService userService;

    //使用方式上同,略
    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
}


现在基本没有这种写法了,如果构造器注入参数太多,就会显得笨重,另外setter的方式能够让类在以后重新配置或者重新注入。

重点就是构造器注入

构造器注入的方式能够保证注入的组件不可变,因为用final修饰了,并且保证需要的依赖不为空。而且,构造器注入的依赖总是能够在返回客户端(组件)代码的时候保证完全初始化的状态

依赖不为空:当要实例化UserController的时候,由于自己实现了有参数的构造函数,所以不会调用默认构造函数,就需要Spring容器传入所需要的参数

1.有该类型的参数 ->传入,

2.无该类型的参数 ->报错,所以保证不会为空

完全初始化的状态:向构造器传参之前,要确保注入的内容不为空,就肯定要调用依赖组件的构造方法完成实例化。而在Java类加载实例化的过程中,构造方法是最后一步。所以返回来的都是初始化之后的状态。

使用构造器注入,在spring项目启动的时候,就会抛出BeanCurrentlyInCreationException:Requested bean is currently in creation: Is there an unresolvable circular reference从而提醒避免循环依赖,如果是field注入的话,启动的时候就不会报错,在使用那个bean的时候才会报错。

使用构造器注入的好处

1.保证依赖不可变(final关键字)

2.保证依赖不为空(省去了我们对其检查)

3.保证返回客户端(调用)的代码的时候是完全初始化的状态

4.避免了循环依赖

5.提升了代码的可复用性