【Spring】——Spring简单 读和取(一)https://developer.aliyun.com/article/1393150
4、方法注解Bean🍉
类注解是添加到某个类上的,而方法注解是放到某个方法上的。
Ⅰ、方法注解要配合类注解使用🍓
Bean注解需要配合五大类注解使用。
ArticleController
package com.demo.component; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; @Component// 将对象存储到 Spring 中 public class ArticleController { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "ArticleController{" + "id=" + id + ", name='" + name + '\'' + '}'; } @Bean//方法注解 public ArticleController acSet(){ ArticleController articleController=new ArticleController(); articleController.setId(1); articleController.setName("java"); return articleController; } }
使用ArticleController中的acSet方法
import com.demo.component.ArticleController; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class App { public static void main(String[] args) { //1、获取spring对象 ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml"); //2、从Spring中取出Bean对象 ArticleController articleController=(ArticleController) context.getBean("acSet");//命名规则和获取Bean一样 //3、使用Bean(可选) System.out.println(articleController); } }
当我们把acSet方法的@Component注解删除时,就会报错:
因此,在使用Bean注解时需要配合使用五大类注解,才能将对象正常的存储到 Spring 容器中
Ⅱ、重命名 Bean🍓
可以通过设置 name 属性给 Bean 对象进行重命名操作。
将acSet方法重命名为ac,并运行代码:
我们可以注意到重命名的name名是使用大括号进行存储,其实这就是一个数组,一个 bean 可以有多个名字。
aS:
import com.demo.component.ArticleController; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class App { public static void main(String[] args) { //1、获取spring对象 ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml"); //2、从Spring中取出Bean对象 ArticleController articleController=(ArticleController) context.getBean("aS"); //3、使用Bean(可选) System.out.println(articleController);//输出:ArticleController{id=1, name='java'} } }
但是需要注意的是,如果进行了重命名原类名就无法再进行获取方法了!
二、获取 Bean 对象(对象装配)[取]🍭
获取 bean 对象也叫做对象装配,是把对象取出来放到某个类中,有时候也叫对象注入。
1、依赖注入的常见方式 🍉
对象装配(对象注入)的实现方法以下 3 种:
- 属性注入
- 构造方法注入
- Setter 注入
刚刚好这里有一篇有关Spring依赖注入的文章,写得很好,我就不重复造轮子了。
面试突击77:Spring 依赖注入有几种?各有什么优缺点? - 掘金 (juejin.cn)
Ⅰ、三种注入优缺点分析🍓
- 属性注入的优点是简洁,使同方便;缺点是只能用于 IoC 容器,如果是非 IoC 容器不可用,并且只有在使用的时候才会出现 NPE(空指针异常)。
- 构造⽅法注入是Spring 推荐的注入方式,它的缺点是如果有多个注⼊会显得比较臃肿,但出现这种情况你应该考虑一下当前类是否符合程序的单一职责的设计模式了,它的优点是通用性,在使用之前⼀定能把保证注⼊的类不为空。
- Setter方式是 Spring 前期版本推荐的注入方式,但通用性不如构造方法,所有 Spring 现版本已经推荐使用构造方法注入的方式来进行类注入了。
2、@Resource:另一种注入关键字🍉
在进行类注入时,除了可以使用 @Autowired 关键字之外,我们还可以使用 @Resource 进行注入
@Autowired 和 @Resource 的区别:
- 出身不同:@Autowired 来自于 Spring,而@Resource 来自于 JDK 的注解;
- 使用时设置的参数不同:相比于 @Autowired 来说,@Resource 支持更多的参数设置,例如 name 设置,根据名称获取 Bean。
- @Autowired 可用于 Setter 注入、构造函数注入和属性注入,而@Resource 只能用于 Setter 注入和属性注入,不能用于构造函数注入。
可以看到 @Resource是JDK自带的方法:
在构造函数注入时, @Resource 会报错:
其实在官方文档中并没有明确指出为什么构造方法不可以使用@Resource,可能是官方类加载顺序的问题或者循环引用的问题。(可以评论区讨论,给出你的看法)
3、同一类型多个 @Bean 报错🍉
User
package com.demo.component; public class User { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "ArticleController{" + "id=" + id + ", name='" + name + '\'' + '}'; } }
Users
package com.demo.component; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; @Component public class Users { @Bean public User user1() { User user = new User(); user.setId(1); user.setName("Java"); return user; } @Bean public User user2() { User user = new User(); user.setId(2); user.setName("MySQL"); return user; } }
UserController
package com.demo.Controller; import com.demo.component.User; import org.springframework.stereotype.Controller; import javax.annotation.Resource; @Controller public class UserController { @Resource private User user; public User getUser(){ return user; } }
运行APP
就可以看到没有唯一Bean定义异常
同一类型多个 Bean 报错处理 🍓
解决同一个类型,多个 bean 的解决方案有以下两个:
- 使用@Resource(name="user1") 定义。
- 使用@Qualifier 注解定义名称。
使用@Resource(name="user1")
使用@Qualifier 注解定义名称