哈喽,大家好,我是小浪。上篇博客我们介绍了五大类注解的使用方法,以及如何解决Spring使用五大类注解生成bean-Name的问题;那么,谈到如何更简单的读取和存储对象,这里我们还需要介绍另外一个”方法注解@Bean”的使用,快来一起学习叭!

目录

一、如何使用方法注解

二、同一类型的对象注入多次的问题

1、精准的描述bean的名称(将注入的名称写对)

2、使用@Resource设置name的方式来重命名注入的对象;

3、使用@AutoWired+@Qualifier来筛选bean对象;

对象注入的三种方法

1、属性注入

2、构造方法注入

3、Setter方法注入

属性注入和构造方法注入以及 Setter 注入的区别是什么?

@Resource VS @Autowired?


一、如何使用方法注解

1、前面介绍过,类注解是写到类上面的,那么方法注解是写到对应的方法上的;

@Bean(name = "user1") public User getUser1() {User user = new User();user.setId(1);user.setName("张三");return user;}

2、方法注解的话是不能够单独使用的,如果我们只给一个方法注解@Bean的话,看是否能运行;

 ApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml"); User user = context.getBean(User.class);//只使用类属性 System.out.println(user);

运行结果:

如何解决?我们只需要在方法注解的类中添加一个类注解即可;

再次运行:

注意Bean 的命名规则,当没有设置 name 属性时,那么 bean 默认的名称就是方法名,当设置了 name 属性之后,只能通过重命名的 name 属性对应的值来获取,也就是说重命名之后,再使用方法名就获取不到 bean 对象;

比如已经给bean重命名了,我们在启动类App中通过方法名来获取Bean对象;

看运行结果:

二、同一类型的对象注入多次的问题

1、在UserBeans类中写两个对象注解;

@Componentpublic class UserBeans {@Bean(name = "user1") // 【注意事项:只使用一个 @Bean 是无法将对象存储到容器中的】public User getUser1() {User user = new User();user.setId(1);user.setName("张三");return user;}@Bean(name = "user2") // 【注意事项:只使用一个 @Bean 是无法将对象存储到容器中的】public User getUser2() {User user = new User();user.setId(2);user.setName("李四");return user;}

2、通过启动类来获取对象;

ApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml");User user = context.getBean(User.class);//只使用类属性System.out.println(user);

运行结果:

翻译过来的意思就是:没有可用的“com.User”类型的合格bean:应为单个匹配bean,但找到2:user1,user2;

那么,如何解决呢?这里我们提供了三种解决方案;

1、精准的描述bean的名称(将注入的名称写对)

比如我们在启动类中使用id+class的形式来取对象;

ApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml");User user = context.getBean("user1",User.class);//只使用类属性System.out.println(user);

运行结果:没有问题;

2、使用@Resource设置name的方式来重命名注入的对象;

1、这里我们通过UserController类来进行演示;注意我们添加的注解@Resource,下面新写了一个对象user1;

package com;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.springframework.stereotype.Controller;import javax.annotation.Resource;@Controllerpublic class UserController {@Resourceprivate User user1;public void sayHi(){System.out.println("User"+user1);}}

启动类App中代码:

ApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml");UserController userController = context.getBean(UserController.class);userController.sayHi();

运行结果:

3、使用@AutoWired+@Qualifier来筛选bean对象;

UserController代码:

package com;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.springframework.stereotype.Controller;import javax.annotation.Resource;@Controllerpublic class UserController {@Autowired@Qualifier(value = "user2")private User user2;public void sayHi(){System.out.println("User"+user2);}}

运行结果:

对象注入的三种方法

1、属性注入

属性注⼊是使⽤ @Autowired 实现的,将 Service 类注⼊到 Controller 类中。

package com;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import javax.annotation.Resource;/** * 根据属性实现 bean 对象的注入 */@Controllerpublic class UserController2 {// 对象注入方式1:属性注入@Autowiredprivate UserService userService;public void sayHi() {userService.sayHi();}}

启动类App:

ApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml");UserController2 userController2 = context.getBean(UserController2.class);userController2.sayHi();

运行结果:

2、构造方法注入

package com;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;/** * 使用构造方法实现 bean 注入 */@Controllerpublic class UserController3 {private UserService userService;// 构造方法注入(官广推荐写法)@Autowiredpublic UserController3(UserService userService) {//userService = new UserService(); // 传统的写法this.userService = userService;}public void sayHi() {userService.sayHi();}}

注:如果当前类只存在一个构造方法,那么@Autowired注解可以省略;

启动类App:

ApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml");UserController3 userController3 = context.getBean(UserController3.class);userController3.sayHi();

运行结果:

3、Setter方法注入

package com;import org.springframework.stereotype.Controller;import javax.annotation.Resource;/** * 使用 Setter 实现 bean 注入 */@Controllerpublic class UserController4 {private UserService userService;@Resourcepublic void setUserService(UserService userService) {this.userService = userService;}public void sayHi() {userService.sayHi();}}

启动类App:

ApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml");UserController4 userController4 = context.getBean(UserController4.class);userController4.sayHi();

运行结果:

属性注入和构造方法注入以及 Setter 注入的区别是什么” />注意:@Resource注解只支持属性注入和Setter注入,不支持构造方法注入;

@Resource VS @Autowired?

出身不同: @Resource 来着与 JDK (Java 亲儿子) ,@Autowired 是 Spring 框架提供的。

2、用法不同: @Autowired 支持属性注入、构造方法注入和 Setter 注入,而 @Resource 不支持构造方法注入。

3、支持的参数不同: @Resource 支持更多的参数设置,比如 name、type 设置;@Autowired 只支持required 参数设置。

OK,今天的学习内容就到这里啦,至此,Spring更简单的读取和存储对象就已经更新完毕了,下篇博客我们会继续更新”bean的作用域和生命周期”,欢迎阅读,感谢订阅!!