【框架篇】对象注入的三种实现方式

对象注入的实现

一,实现方式的使用

对象注入也可被称为对象装配,是把Bean对象获取出来放到某个类中。

对象注入的实现方式有3种,分别为属性注入,Setter注入和构造方法注入。

为了更好地理解对象注入的实现方式,搞个实例来具体说明:

1.0,前期准备

1,准备Service类

java 复制代码
@Service
public class StudentService {
    public void sayHi(){
        System.out.println("do student service sayHi()");
    }
}

示例问题:将 Service 类注入到 Controller 类中,对象注入实现:

1.1,属性注入

1,方式对应实现的Controller 类代码:

java 复制代码
@Controller
public class StudentController {
    //注入方式:属性注入
    @Autowired
    private StudentService studentService;
    public void sayHi(){
        System.out.println("do student controller sayHi()");
        studentService.sayHi();
    }
}

2,启动类实现代码:

java 复制代码
public class App {
    public static void main(String[] args) {
        //1,获取Spring上下文
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("spring-config.xml");
        //2,得到Bean对象
        StudentController studentController =
                applicationContext.getBean("studentController",StudentController.class);
        //3,使用Bean对象
        studentController.sayHi();
    }
}

3,启动类执行结果:

1.2,Setter注入

1,方式对应实现的Controller 类代码:

java 复制代码
@Controller
public class StudentController {
    private StudentService studentService;
    @Autowired
    public void setStudentService(StudentService studentService) {
        this.studentService = studentService;
    }
    public void sayHi(){
        System.out.println("do student controller sayHi()");
        studentService.sayHi();
    }
}

2,启动类实现代码:

java 复制代码
public class App {
    public static void main(String[] args) {
        //1,获取Spring上下文
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("spring-config.xml");
        //2,得到Bean对象
        StudentController studentController =
                applicationContext.getBean("studentController",StudentController.class);
        //3,使用Bean对象
        studentController.sayHi();
    }
}

3,启动类执行结果:

1.3,构造方法注入

1,方式对应实现的Controller 类代码:

java 复制代码
@Controller
public class StudentController {
    private StudentService studentService;
    @Autowired
    public StudentController(StudentService studentService) {
        this.studentService = studentService;
    }
    public void sayHi(){
        System.out.println("do student controller sayHi()");
        studentService.sayHi();
    }
}

2,启动类实现代码:

java 复制代码
public class App {
    public static void main(String[] args) {
        //1,获取Spring上下文
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("spring-config.xml");
        //2,得到Bean对象
        StudentController studentController =
                applicationContext.getBean("studentController",StudentController.class);
        //3,使用Bean对象
        studentController.sayHi();
    }
}

3,启动类执行结果:


二,方式的优缺点分析

2.1,属性注入

1,方式实现代码:

2,方式优点:

  • 实现简单,易于理解和维护

3,方式缺点:

  • 不能注入不可变对象【final 修饰的变量】
  • 通用性差,只适用于IoC容器,在非IoC框架中无效
  • 更容易违背单一设计原则

2.2,Setter注入

1,方式实现代码:

2,方式优点:

  • 符合单一设计原则【每个方法只传递一个对象】

3,方式缺点:

  • 不能注入不可变对象【final 修饰的变量】

  • 使用Setter注入的对象可能被修改

2.3,构造方法注入

1,方式实现代码:

注意:如果只有一个构造方法,那么 @Autowired 注解可以省略。

2,方式优点:

  • 可以注入不可变对象【final 修饰的变量】

  • 注入对象不会被改变【构造方法只执行一次】

  • 注入对象会完全被初始化

  • 通用性更好,可在IoC容器中使用,也可在非IoC中使用

3,方式缺点:

  • 不符合单一设计原则【每个方法可传递多个对象】

三,对象注入中的问题

3.1,@Autowired 和 @Resource

在进行类注入时,除了可以使用@Autowired注解之外,我们还可以使用@Resource注解进行注入。

@Autowired@Resource 都是在 Spring 框架中用于注入依赖的注解,它们有以下区别:

  1. 来源不同:
    • @Autowired 是 Spring 框架提供的注解,通过类型进行依赖注入。
    • @Resource 是 JavaEE 定义的注解,通过名称进行依赖注入。
  2. 注入方式不同:
    • @Autowired 默认按照类型匹配的方式进行注入,如果存在多个相同类型的实例,可以结合 @Qualifier 注解来指定具体实例。
    • @Resource 默认按照名称匹配的方式进行注入,它支持使用 nametype 属性来指定名称或类型进行匹配。
  3. 支持的类型不同:
    • @Autowired 支持通过构造方法注入、属性注入、Setter 注入的方式实现依赖注入。
    • @Resource 支持通过属性注入、Setter 注入的方式实现依赖注入,不支持构造方法注入。
  4. 应用范围不同:
    • @Autowired 主要用于 Spring 框架中的组件(如 Spring Bean)的依赖注入。
    • @Resource 是 JavaEE 规范中的注解,它可以用于依赖注入和资源的获取,对于不依赖于 Spring 框架的应用也可以使用。

3.2,同⼀类型多个 @Bean 报错

当出现多个 Bean 返回同⼀对象类型时,程序会报错。解决同一个类型,多个bean的解决方案有以下两个:

1,使用 @Resource(name="")

2,搭配 @Autowired 使用 @Qualifierr(value = "")


核心总结

1,三种对象注入的实现方式以及优缺点?

属性注入,Setter注入和构造方法注入是在依赖注入中常用的三种方式,它们各有优缺点:

1,属性注入方式:其实现简单,易于理解和维护,但是其不能注入不可变对象,只适用于IoC容器,并且违反单一设计原则的概率大。

2,Setter注入方式:其符合单一设计原则,但是其不能注入不可变对象,并且使用Setter注入的对象可能被修改。

3,构造方法注入方式:其可以注入不可变对象,注入的对象不能被改变,保证注入对象完全被初始化,并且具有通用性,但是其不符合单一设计原则。

注意:在上述的三种对象注入的实现方式中,构造方法注入是Spring推荐的注入方式。


思考:为什么构造方法可以注入不可变变量,而属性注入和Setter注入却不行呢?

解答:在 Java 中,被final修饰的对象,要么直接进行赋值,要么就在构造方法中进行赋值,两种情况必须满足一个,否则方式报错。


2,@Autowired 和 @Resource 注入注解的区别?

@Autowired@Resource 都是在 Spring 框架中用于注入依赖的注解,它们有以下区别:

1,来源不同:@Autowired 是 Spring 框架提供的注解,而@Resource 是 JavaEE 定义的注解。

2,注入方式不同:@Autowired 默认按照类型匹配的方式进行注入,而@Resource 默认按照名称匹配的方式进行注入。

3,支持的类型不同:@Resource 支持通过属性注入、Setter 注入的方式实现依赖注入,不支持构造方法注入,而@Autowired 支持。

4,应用范围不同:@Autowired 主要用于 Spring 框架中的组件的依赖注入,而@Resource对于不依赖于 Spring 框架的应用也可使用。


3,同⼀类型多个 @Bean 报错的解决方案有哪些?

解决同一个类型 @Bean 报错的解决方案有以下两个:

  1. 使用 @Resource(name="")
  2. 使用 @Qualifierr(value = "") 【搭配@Autowired使用】

结语

这就是本期博客的全部内容啦!如果有什么其他的问题无法自己解决,可以在评论区留言哦!

最后,如果你觉得这篇文章写的还不错的话或者有所收获的话,麻烦小伙伴们动动你们的小手,给个三连呗(点赞👍,评论✍,收藏📖),多多支持一下!各位的支持是我最大的动力,后期不断更新优质的内容来帮助大家,一起进步。那我们下期见!


相关推荐
xyy20255 小时前
Spring事务的传播方式
java·数据库·spring
不能再留遗憾了10 小时前
【SpringCloud】Sentinel
spring·spring cloud·sentinel
whltaoin11 小时前
AI 超级智能体全栈项目阶段五:RAG 四大流程详解、最佳实践与调优(基于 Spring AI 实现)
java·人工智能·spring·rag·springai
心勤则明12 小时前
Spring AI 文档ETL实战:集成text-embedding-v4 与 Milvus
人工智能·spring·etl
艾菜籽12 小时前
Spring Web MVC入门补充1
java·后端·spring·mvc
艾菜籽15 小时前
Spring MVC入门补充2
java·spring·mvc
为java加瓦18 小时前
Spring 方法注入机制深度解析:Lookup与Replace Method原理与应用
java·数据库·spring
无名客018 小时前
SpringCloud中的网关(Gateway)的作用是什么?
spring·spring cloud·gateway
hrrrrb20 小时前
【Spring Security】Spring Security 概念
java·数据库·spring
小信丶20 小时前
Spring 中解决 “Could not autowire. There is more than one bean of type“ 错误
java·spring