常见面试题-依赖注入原理

依赖注入原理

参考文章:https://www.51cto.com/article/716969.html

Spring 中的依赖注入是通过反射来实现的,当 IOC 容器创建 Bean 的时候,会检查 Bean 中定义的依赖关系,并且尝试通过反射来注入这些依赖关系

Spring 的依赖注入有三种方式:

  • 属性注入

    java 复制代码
    @RestController
    public class UserController {
        // 属性对象
        @Autowired
        private UserService userService;
    
        @RequestMapping("/add")
        public UserInfo add(String username, String password) {
            return userService.add(username, password);
        }
    }

    优点:

    • 使用简单,添加 @Autowired 即可

    缺点:

    • 无法注入一个不可变对象(final 修饰),因为 Java 中的 final 对象,要么初始直接赋值,要么在构造方法中赋值,如果使用属性注入 final 对象,不符合 Java 的 final 使用规范

      java 复制代码
      @Autowired
      private final UserService userService;
    • 与 IOC 容器耦合度过高,只能适用于 IOC 容器,其他非 IOC 框架不一定支持属性注入

    • 可能违背单一职责原则,通过属性注入比较简单,可能造成滥用,在一个类中引入多个属性依赖,引入的越多则承担了越多的责任,违背单一职责原则的可能性越大

  • Setter 注入

    java 复制代码
    @RestController
    public class UserController {
        // Setter 注入
        private UserService userService;
    
        @Autowired
        public void setUserService(UserService userService) {
            this.userService = userService;
        }
    
        @RequestMapping("/add")
        public UserInfo add(String username, String password) {
            return userService.add(username, password);
        }
    }

    优点:

    • setter 注入只针对一个对象,符合单一职责原则

    缺点:

    • 不能注入不可变对象(final 修饰的对象)
    • 注入的对象可被修改(在注入之后,如果在其他地方调用 setXX 会改变注入的对象)
  • 构造方法注入

    Spring 4.x 之后推荐的注入方式

    如果只有一个构造方法,可以不用在构造方法上添加 @Autowired,如下边代码,可以去掉 @Autowired 注解:

    java 复制代码
    @RestController
    public class UserController {
        // 构造方法注入
        private UserService userService;
    
        @Autowired
        public UserController(UserService userService) {
            this.userService = userService;
        }
    
        @RequestMapping("/add")
        public UserInfo add(String username, String password) {
            return userService.add(username, password);
        }
    }

    优点:

    • 可以注入不可变对象
    • 注入对象不会被修改
    • 通用性更好,无论是 IOC 框架还是非 IOC 框架,构造方法注入的代码都是通用的
相关推荐
yangyanping20108几秒前
Go语言学习之配置管理库Viper
开发语言·学习·golang
橘子编程3 分钟前
UniApp跨端开发终极指南
开发语言·vue.js·uni-app
LJianK17 分钟前
Java类的实例化对象,和引用
java
sinat_255487818 分钟前
泛型:超级、扩展、列表·学习笔记
java·windows·学习·算法
冬至喵喵9 分钟前
构建 CLI 的 Python 框架:Typer技术介绍
开发语言·chrome·python
何故染尘優10 分钟前
如何快速判断几十亿个数中是否存在某个数?
java
REDcker11 分钟前
C++ 多线程内存模型与 memory_order 详解
java·c++·spring
AbandonForce13 分钟前
STL list
开发语言·c++
MegaDataFlowers14 分钟前
解决启动Tomcat在idea输出日志乱码问题
java·ide·intellij-idea
前端老石人14 分钟前
HTML 入门指南:从规范视角建立正确知识体系
开发语言·前端·html