SpringBoot 依赖注入方式
前置知识
- Spring DI(Dependency Injection)依赖注入:组件之间依赖关系由容器在运行期间决定,即
由容器动态的将某个依赖关系注入到组件中
- 谁依赖谁:应用程序依赖IOC容器
- 为什么需要依赖:应用程序需要IOC容器提供对象需要的外部资源
- 谁注入谁:IOC容器注入应用程序某个对象,应用程序依赖的对象
- 注入了什么:注入某个对象所需要的外部资源,包括对象、资源、常量数据等
- Spring DI 是
通过反射实现
的,它允许程序在运行期间动态的生成对象、执行对象的方法、改变对象的属性
依赖注入的方式
前置代码
public interface OrderService {
Order getOrder();
}
@Service
public class OrderServiceImpl implements OrderService{
@Override
public Order getOrder() {
return new Order();
}
}
属性注入
@Resource
Java提供的注解,存在两个属性:name、type。在Spring中是通过name
属性来解析Bean的名字,而type
属性解析Bean的类型- 如果使用
name
属性时,通过name
指定的值自动注入 - 如果使用
type
属性时,通过type
指定的值自动注入 - 如果都不指定
name
或者type
属性时,通过反射机制使用name
属性自动注入
- 如果使用
@Autowired
Spring提供的注解,只能根据type
进行注入,如果type
无法识别注入对象时,需要依赖@Qualifier
注解通过value
属性指定Bean的名称注入或者通过@Primary
的注解,解决依赖注入的歧义时决定要注入哪个Bean@Value
注解一般使用读取配置文件的,该注解所在的类必须被Spring容器所管理
/**新增一个OrderService实现类,用于@Qualifier注解*/
@Service
public class OrderServiceImpl2 implements OrderService{
@Override
public Order getOrder() {
return new Order();
}
}
@RestController
@RequestMapping("/order")
public class OrderController {
/**读取配置文件中的值*/
@Value("${server.port}")
private String port;
/**属性注入:通过注解 @Autowired*/
@Autowired
private OrderService orderService;
/**属性注入:通过注解 @Autowired + @Qualifier(value="") 指定要注入的类*/
/**
@Autowired
@Qualifier("orderServiceImpl2")
private OrderService orderService;
*/
/**属性注入:通过注解 @Resource */
/**
@Resource
private OrderService orderService;
*/
@GetMapping("/getOrder")
public Order getOrder(){
return orderService.getOrder();
}
}
setter方法注入(不推荐)
@RestController
@RequestMapping("/order")
public class OrderController {
private OrderService orderService;
/**setter方式注入,需要配合使用@Autowired注解*/
@Autowired
public void setOrderService(OrderService orderService){
this.orderService = orderService;
}
@GetMapping("/getOrder")
public Order getOrder(){
return orderService.getOrder();
}
}
构造器注入(推荐)
构造器注入的方式能够保证注入的组件不可变(因为属性使用final修饰
了),并且确保需要的依赖不为空
,还能避免出现循环依赖
问题(如存在循环依赖,则在容器启动时就会报错)。构造器注入的依赖总是能够在返回客户端(组件)代码的时候保证完全初始化的状态
@RestController
@RequestMapping("/order")
public class OrderController {
private final OrderService orderService;
/**构造器方式注入*/
public OrderController(OrderService orderService){
this.orderService = orderService;
}
@GetMapping("/getOrder")
public Order getOrder(){
return orderService.getOrder();
}
}
注意点:类中属性没被final修饰时,不能存在无参的构造函数,否则属性就会被赋值为null