Spring为什么这么火 之 各种依赖注入及其优缺点

目录

前言

Spring中实现依赖注入的常见方式:

1、属性注入(Field Injection)【平时最常用的】

1.1、 @Autowired实现属性注入

属性注入的优缺点:

2、Setter注入(Setter Injection)

setter注入的优缺点

3、构造方法注入(Construction injection)【Spring官方推荐】

构造方法注入的优缺点

4、@Resource注解 

@Resource  VS  @Autowired

5、同一类型多个@Bean报错

处理一:使用@Resource注解:

 处理二:使用@Qualifier注解定义名称

 小结:


前言

Spring中实现依赖注入的常见方式:

  1. 属性注入(Field Injection);
  2. Setter注入(Setter Injection);
  3. 构造方法注入(Construction Injection)

不会创建项目的小伙伴们,可以去我的主页往期中有介绍【依赖、配置等】,这一期就不介绍啦~ 


1、属性注入(Field Injection)【平时最常用的】

1.1、 @Autowired实现属性注入

属性注入是使用@Autowired实现的,将Service类注入到Controller类中

查看我这目录:

 

UserService中的代码:

package com.Service;

import org.springframework.stereotype.Service;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User:龙宝
 * Date:2023-02-07
 * Time:14:51
 */

@Service
public class UserService {
    public void sayHi() {
        System.out.println("Hi,Service");
    }
}

UserController中的代码:

package com.controller;

import com.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User:龙宝
 * Date:2023-02-07
 * Time:14:50
 */
@Controller
public class UserController {
    //属性注入:

    @Autowired
    private UserService userService;

    public void sayHi() {
        userService.sayHi();
    }
}

Test中的代码:

package com;

import com.Service.UserService;
import com.controller.UserController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User:龙宝
 * Date:2023-02-07
 * Time:15:11
 */
public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

        UserController userController = context.getBean("userController",UserController.class);
        userController.sayHi();
    }
}

输出:

属性注入的代码核心:

属性注入的优缺点:

 优点

  • 实现简单

缺点

  •  不能注入不可变对象【final修饰】
  • 只适用于IoC容器
  • 更容易违背单一设计原则【针对的对象是类】

2、Setter注入(Setter Injection)

Setter注入和属性注入方法实现类似,只是注解是加在set方法上

代码核心:

 UserController_Setter中的代码:

package com.controller;

import com.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User:龙宝
 * Date:2023-02-07
 * Time:15:33
 */
@Controller
public class UserController_Setter {

    //setter注入:

    private UserService userService;

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

    public void sayHi() {
        userService.sayHi();
    }
}

setter注入的优缺点

优点:

  • 更加符合单一设计原则【针对的对象是方法】

缺点:

  • 不能注入不可变对象
  • 注入对象可被修改【set方法是普通方法,可以被重复调用】

3、构造方法注入(Construction injection)【Spring官方推荐】

构造方法注入就是在类的构造方法中实现注入

核心代码:

 UserController_Constructor中的代码:

package com.controller;

import com.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User:龙宝
 * Date:2023-02-07
 * Time:15:41
 */

@Controller
public class UserController_Constructor {

    //构造方法注入:
    private UserService userService;

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

    public void sayHi(){
        userService.sayHi();
    }
}

构造方法注入的优缺点

优点:

  • 可以注入一个不可变对象
  • 注入的对象不会被改变【一方面是加了final修饰符,另一方面是构造方法随着类加载只执行一次】
  • 注入的对象会被完全初始化
  • 通用性更好

缺点:

  • 没有属性注入实现简单

4、@Resource注解 

@Resource注解是JDK自带的注解

使用:

 这里的属性注入和setter注入和@Autowired是很类似的

@Resource  VS  @Autowired

相同点:

  • 都是用来实现依赖注入的

不同点:

  • 功能支持:@Autowired支持属性注入、setter注入、构造方法注入;@Resource支持属性注入、setter注入,不支持构造方法注入
  • 出身不同:@Autowired来自Spring框架;@Resource来自于JDK
  • 参数支持不同:@Resource支持更多的参数设置;@Autowired只支持required参数

5、同一类型多个@Bean报错

目录:

 我圈出来的目录是我们所在需要的:

首先需要一个User类:

package com.model;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User:龙宝
 * Date:2023-02-07
 * Time:16:19
 */
public class User {
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    private String name;
    private int age;


}

接下来是,UserBeans类,这里使用伪代码,只是方便我们去验证,实际工作中并不会这样子:

package com.component;

import com.model.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User:龙宝
 * Date:2023-02-07
 * Time:16:17
 */
@Component
public class UserBeans {

    @Bean
    public User user1() {
        //伪代码
        User user = new User();
        user.setName("lyj");
        user.setAge(19);
        return user;
    }

    @Bean
    public User user2() {
        User user = new User();
        user.setName("cyk");
        user.setAge(20);
        return user;
    }
}

再接下来就是UserController类:

package com.controller;

import com.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User:龙宝
 * Date:2023-02-07
 * Time:16:35
 */
@Controller
public class UserController {

    @Autowired
    private User user;

    public User getUser() {
        return user;
    }


}

最后在Test中运行:

package com;

import com.controller.UserController;
import com.controller.UserController1;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User:龙宝
 * Date:2023-02-07
 * Time:15:11
 */
public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

        UserController userController = context.getBean("userController", UserController.class);
    }
}

结果:

 报错了,仔细看报错原因,

我们会看到:

 也就是:同一类型多个@Bean报错

 怎么处理:

处理一:使用@Resource注解:

 处理二:使用@Qualifier注解定义名称

 这里括号中名字怎么来的:

 小结:

  • 从Spring中获取对象:属性注入;Setter注入;构造方法注入
  • 注入关键字:@Autowired;@Resource
  • @Autowired和@Resource 不同:出身不同,参数设置不同【Resource支持更多参数设置,如name】
  • 解决同一类型多个Bean报错:使用@Resource(name = “”);使用@Qualifier(“”)

本期结束啦,咱们下期见啦! 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙洋静

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值