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

相关推荐
Ulyanov15 小时前
用Pyglet打造AI数字猎人:从零开始的Python游戏开发与强化学习实践
开发语言·人工智能·python
独自归家的兔16 小时前
OCPP 1.6 协议详解:StatusNotification 状态通知指令
开发语言·数据库·spring boot·物联网
希望永不加班16 小时前
Spring AOP 代理模式:CGLIB 与 JDK 动态代理区别
java·开发语言·后端·spring·代理模式
RNEA ESIO16 小时前
PHP进阶-在Ubuntu上搭建LAMP环境教程
开发语言·ubuntu·php
234710212716 小时前
4.15 学习笔记
开发语言·软件测试·python
eggwyw17 小时前
基于SpringBoot和PostGIS的云南与缅甸的千里边境线实战
java·spring boot·spring
浮游本尊17 小时前
一次合同同步背后的多阶段流水线:从外部主数据到本地歧义消解
后端
lv__pf17 小时前
springboot原理
java·spring boot·后端
java1234_小锋17 小时前
Java高频面试题:什么是可重入锁?
java·开发语言