Spring 中简单存取 Bean 的相关注解(三)

简介: Spring 中简单存取 Bean 的相关注解

多个同类型 Bean 注入怎么办?


问题:如若有多个同类型的 Bean 对象存储进 IoC 容器中,那么我们该如何准确获取该类型对象?


问题场景:


Users 类:


@Service
public class Users {
  //通过方法注解,添加两个同类型 bean
    @Bean("user1")
    public User user1() {
        User user = new User();
        user.setName("李四");
        user.setId(22);
        return user;
    }
    @Bean("user2")
    public User user2() {
        User user = new User();
        user.setName("王五");
        user.setId(88);
        return user;
    }
}


UserService 类:


@Service
public class UserService {
  //对 user 进行属性注入
    @Autowired
    User user;
    public void add() {
      //拿到 user 后打印内容,判断是哪个 user
        System.out.println(user.toString());
    }
}


Test 类:


public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
        UserService userService = context.getBean("userService", UserService.class);
        userService.add();
    }
}


看结果:4c222721364c483da2ad81cb96fae35b.png


它是说期望有一个 bean 进行匹配,但出现了两个:user1、user2


解决问题:


1.将属性的名字和 Bean 的名字对应上。

就比如我要得到的是 王五 这个对象,那我只需要将下面两点的名称对应上即可:


62db5acfff784753ae53cc6ae95250ed.pngf41769b3bfd54f77a0784c680c3a29f0.png

2882b979cc3b4c5fb7c7c6cb2ff93fad.png


2.@Autowired 配合 @Qualifier 使用

这个就是在注入时,声明要注入的 bean 名称

2a7a2fe6b87c4f4092ed8c81c5db9977.png


属性注入分析:

优点: 使用简单

缺点:


  1. 无法注入 final 修饰的变量
  2. 只适用于 IoC 容器
  3. 容易违背单一设计原则


Setter 注入


我们写类属性时,可以对这些属性生成相应的 get 和 set 方法,Setter 注入就是针对 set 方法,进行的注入:


User 类:


@Service
public class Users {
        @Bean("user")
        public User getUser() {
            User user = new User();
            user.setName("老王");
            user.setId(26);
            return user;
        }
}


UserService 类:


@Service
public class UserService {
    private User user;
  //对类属性 user 进行 Setter 注入
    @Autowired
    public void setUser(User user) {
        this.user = user;
    }
    public void add() {
        System.out.println(user.toString());
    }
}


public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
        UserService userService = context.getBean("userService", UserService.class);
        userService.add();
    }
}


注意:@Autowired 不能省略


Setter 注入分析:

优点:通常 Setter 只是注入一个属性,所以 Setter 更符合单一设计原则。

缺点:


  1. 无法注入一个 final 修饰的变量
  2. Setter 注入的对象可以被修改。(setter 是一个方法,既然是方法就可能被多次调用和修改)


构造方法注入(官方推荐)


构造⽅法注⼊是在类的构造⽅法中实现注⼊,如下代码所示:


只对 UserService 进行修改:


@Service
public class UserService {
    private User user;
  //构造方法注入
    @Autowired
    public UserService(User user) {
        this.user = user;
    }
    public void add() {
        System.out.println(user.toString());
    }
}


注意:如果只有一个构造方法,不写 @Autowired 也可以,但若是有多个构造方法,就得加上 @Autowired,表明是哪个构造方法需要注入。


构造方法注入分析:

优点:

  1. 可以注入一个 final 修饰的变量
  2. 注入的变量不会被修改,因为构造方法只加载一次
  3. 构造方法注入可以保证注入对象完全初始化
  4. 构造方法注入通用性更好


缺点:

  1. 写法比属性注入更复杂
  2. 使用构造方法注入,无法解决循环依赖的问题

其实 @Resource 的功能和 @Autowired 差不多,那它俩有啥区别呢?


@Autowired 与 @Resource 的区别:


  1. 出生不同:@Resource 来自 JDK,@Autowired 来自 Spring 框架
  2. 支持参数不同:@Resource 支持很多参数设置,@Autowired 只支持一个参数设置
  3. 使用上的区别:@Resource 不支持构造方法注入,@Autowired 支持构造方法注入
  4. idea 兼容性支持不同:使用 @Autowired 在 idea 专业版下可能会误报,@Resource 不存在误报问题(@Resource 相当于是亲儿子了)

关于第四点:因为@Autowired 来自 Spring 框架,@Resource 来自 JDK,所以执行顺序有差异,Spring 框架的执行是在 java 程序执行之后的,当我们使用 @Autowired 时,它不能检测到 IoC 容器中是否有这个类型的 Bean,所以就报错(运行起来不影响结果);使用 @Resource 的话,执行顺序是靠前的,它知道这个 Bean 是否存在。


相关文章
|
9天前
|
Java Spring
【Spring】方法注解@Bean,配置类扫描路径
@Bean方法注解,如何在同一个类下面定义多个Bean对象,配置扫描路径
136 73
|
4天前
|
Java Spring 容器
【SpringFramework】Spring IoC-基于注解的实现
本文主要记录基于Spring注解实现IoC容器和DI相关知识。
37 21
|
9天前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
|
9天前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
|
9天前
|
Java Spring
【Spring配置】idea编码格式导致注解汉字无法保存
问题一:对于同一个项目,我们在使用idea的过程中,使用汉字注解完后,再打开该项目,汉字变成乱码问题二:本来a项目中,汉字注解调试好了,没有乱码了,但是创建出来的新的项目,写的注解又成乱码了。
|
14天前
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
52 6
|
7月前
|
Java 开发者 Spring
解析Spring中Bean的生命周期
解析Spring中Bean的生命周期
64 2
|
7月前
|
XML druid Java
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
75 0
|
3月前
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细解析Spring Bean的生命周期及其核心概念,并深入源码分析。Spring Bean是Spring框架的核心,由容器管理其生命周期。从实例化到销毁,共经历十个阶段,包括属性赋值、接口回调、初始化及销毁等。通过剖析`BeanFactory`、`ApplicationContext`等关键接口与类,帮助你深入了解Spring Bean的管理机制。希望本文能助你更好地掌握Spring Bean生命周期。
147 1
|
3月前
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细介绍了Spring框架中的核心概念——Spring Bean的生命周期,包括实例化、属性赋值、接口回调、初始化、使用及销毁等10个阶段,并深入剖析了相关源码,如`BeanFactory`、`DefaultListableBeanFactory`和`BeanPostProcessor`等关键类与接口。通过理解这些核心组件,读者可以更好地掌握Spring Bean的管理和控制机制。
112 1