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 是否存在。


相关文章
|
6天前
|
安全 Java Spring
Spring框架中的单例Bean是线程安全的吗?
Spring框架中的单例Bean是线程安全的吗?
10 1
|
5天前
|
Java
Springboot 使用自定义注解结合AOP方式校验接口参数
Springboot 使用自定义注解结合AOP方式校验接口参数
Springboot 使用自定义注解结合AOP方式校验接口参数
|
6天前
|
XML 前端开发 Java
【JavaEE】深入了解Spring中Bean的可见范围(作用域)以及前世今生(生命周期)
【JavaEE】深入了解Spring中Bean的可见范围(作用域)以及前世今生(生命周期)
9 0
|
6天前
|
存储 缓存 Java
【JavaEE】Spring中注解的方式去获取Bean对象
【JavaEE】Spring中注解的方式去获取Bean对象
3 0
|
6天前
|
存储 Java 对象存储
【JavaEE】Spring中注解的方式去存储Bean对象
【JavaEE】Spring中注解的方式去存储Bean对象
9 0
|
6天前
|
存储 Java 对象存储
【JavaEE】DI与DL的介绍-Spring项目的创建-Bean对象的存储与获取
【JavaEE】DI与DL的介绍-Spring项目的创建-Bean对象的存储与获取
9 0
|
11月前
|
XML Java 数据库连接
【Spring学习笔记 五】Spring注解及Java类配置开发
【Spring学习笔记 五】Spring注解及Java类配置开发
71 0
|
XML Java 数据格式
spring基于注解的配置
**不管是 XML 还是注解,它们都是表达 Bean 定义的载体,其实质都是为 Spring 容器提供 Bean 定义的信息,在表现形式上都是将 XML 定义的内容通过类注解进****行描述。**Spring 从2.0开始就引入了基于注解的配置方式,在2.5时得到了完善,在4.0时进一步增强。
|
XML Java 数据格式
Spring(七)之基于注解配置
基于注解的配置 从 Spring 2.5 开始就可以使用注解来配置依赖注入。而不是采用 XML 来描述一个 bean 连线,你可以使用相关类,方法或字段声明的注解,将 bean 配置移动到组件类本身。 在 XML 注入之前进行注解注入,因此后者的配置将通过两种方式的属性连线被前者重写。
741 0
|
前端开发 Java 数据库连接
spring(四)之基于注解(Annotation-based)的配置
注解 Autowired 可以用于传统的setter 方法 用于以属性为参数多个参数的方法 用于构造器与字段 ApplicationContext - 用于集合类型 Maps 缺省情况 Qualifier注解 创建您自定义的限定器注解 定义一个注解时提供Qual...
1288 0