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 

posted @ 2023-05-12 22:35  伊文小哥  阅读(545)  评论(0编辑  收藏  举报