Bean的三种注入方式

说明:本文介绍 Spring Boot 中三种注入 Bean 的方式。

场景

写两个接口,两个实现类

(OrderService)

java 复制代码
public interface OrderService {

    String test();
}

(UserService)

java 复制代码
public interface UserService {

    String test();
}

(OrderServiceImpl)

java 复制代码
import com.hezy.demo.OrderService;
import org.springframework.stereotype.Service;

@Service
public class OrderServiceImpl implements OrderService {

    @Override
    public String test() {
        return "order";
    }
}

(UserServiceImpl)

java 复制代码
import com.hezy.demo.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
    
    @Override
    public String test() {
        return "user";
    }
}

写一个接口,调用 OrderService,实现类中注入 UserService,共同完成接口。

java 复制代码
import com.hezy.demo.OrderService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
public class DemoController {

    @Resource
    private OrderService orderService;

    @GetMapping("/test")
    public String test2(){
        return orderService.test();
    }
}

基于以上场景,介绍在 OrderService 实现类中,注入 UserService 的三种方式。

方式一:属性注入

如下,直接定义变量,使用 @Autowired 注解,或者 @Resource 注解,完成注入。这种方式也叫字段注入。

java 复制代码
    @Autowired
    private UserService userService;

或者

java 复制代码
    @Resource
    private UserService userService;

方式二:构造器注入

如下,定义一个 Bean 属性,在 OrderService 实现类的构造器中完成注入。

java 复制代码
import com.hezy.demo.OrderService;
import com.hezy.demo.UserService;
import org.springframework.stereotype.Service;

@Service
public class OrderServiceImpl implements OrderService {
    
    private final UserService userService;

    public OrderServiceImpl(UserService userService) {
        this.userService = userService;
    }
}

方式三:接口注入

创建一个接口,用来装配 UserService Bean,如下:

java 复制代码
public interface UserServiceBean {

    void setUserService(UserService userService);
}

让 OrderService 的实现类,实现这个接口

java 复制代码
@Service
public class OrderServiceImpl implements OrderService, UserServiceBean {

因为 Spring 不支持接口注入,这里手动在 IOC 容器中查找,完成注入

java 复制代码
    private UserService userService;

    @Autowired
    private ApplicationContext context;

    @PostConstruct
    public void init() {
        setUserService(context.getBean(UserService.class));
    }

    @Override
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

测试

在 OrderService 实现类中,调用注入的 UserService 方法,拼接方法返回值,返回接口。

java 复制代码
    @Override
    public String test() {
        String user = userService.test();
        return user + "-" + "order";
    }

启动项目,三种注入方式均可以正常注入。

另外

另外,还有两种注入情况,如下,

java 复制代码
    private UserService userService;

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

或者

java 复制代码
    private UserService userService;
    
    public OrderServiceImpl(@Autowired UserService userService) {
        this.userService = userService;
    }

在构造器注入的基础上额外使用 @Autowired 注解,不加也行,是 Spring 旧版本的写法。

相关推荐
马艳泽几秒前
win11环境查找jar包中字符串
后端
buhuizhiyuci1 分钟前
【QT-百日筑基篇】功法有些小成,开始进行打怪升级-QT的实践第一课,创建Hello World的几种方法
开发语言·qt
宁&沉沦7 分钟前
后端各框架热启动 极简启动命令(直接复制用)
后端
枕星而眠7 分钟前
Linux 共享内存与信号量全解析:原理、实践与避坑指南
linux·c语言·开发语言·后端·ubuntu
kree8 分钟前
Meilisearch:轻量搜索引擎的优雅选择,以及它在 RAG 中的应用
后端
Sanri.11 分钟前
JavaScript基础语法6
开发语言·javascript·ecmascript
hhb_61814 分钟前
JavaScript核心技术要点梳理与实战应用案例解析
开发语言·javascript·ecmascript
Mike117.15 分钟前
GBase 8a DBLink 查询的落地边界和排查细节
开发语言·php
代码中介商15 分钟前
C++ STL入门:vector与字符串流详解
开发语言·c++
Ting-yu16 分钟前
SpringCloud快速入门(2)---- SpringCloud简介
后端·spring·spring cloud