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 旧版本的写法。

相关推荐
萨小耶几秒前
[Java学习日记10】聊聊checked exception和runtime exception
java·开发语言·学习
404号扳手2 分钟前
Java 进阶知识(八)
java·后端
PILIPALAPENG2 分钟前
Skills篇-findskills:告别手动迁移Skill!跨AI工具通用能力,才是真高效
前端·人工智能·后端
不会C语言的男孩5 分钟前
C++ Primer 第6章:函数
开发语言·c++
honeymoose8 分钟前
Pnpm approve-builds --all Jenkins 第一次构建总是出错
后端
浮游本尊8 分钟前
Java学习第39天 - API 自动化测试、MockMvc 与可观测性日志
后端
dnbug Blog10 分钟前
C语言 简介
c语言·开发语言
Lumbrologist10 分钟前
【C++】零基础入门 · 第 18 节:互斥锁与线程同步
java·开发语言·c++
程序员cxuan11 分钟前
太顶了,ChatGPT 要和 Codex 搞一起了。
人工智能·后端·程序员
算法印象派13 分钟前
Rokid AI 眼镜远程协作应用"一线互联"开发实践:重连机制与凭据缓存
后端