前言
入门
就是对象交给spring来创建
在上面加上Component的意思是,这个类可以交给spring自己来创建
现在service和dao都交给spring来创建了
怎么取出来呢
在成员上面加上Autowired,就可以让spring自己来创建了
这样我们就不用new了
spring就帮我们new完了
如果没有new的话,就是null的
这样就可以运行了
不加Component的话都启动不起来,因为没有加入spring
不加Autowired的话就会报错,因为为null
bean的存储
controller
有了controller,spring就会帮我们创建一个这个对象
然后去调用对应的方法
启动类会去创建这个类
启动类先创建spring容器
就是这样调用了
没有controller注解,spring就没有这个类,就找不到这个对象
ConfigurableApplicationContext就是容器,就是spring的运行环境
包括bean的对象
getBean这个方法有很多方式获取bean
我们上面演示的是类的class属性,这个是唯一的
当然每个类都可以有一个bean的名称,这个也是唯一的
我们也可以根据名称来获取bean
一般来说,就是类名,但是有规范
UserController类名–》userController参数名
UController-》》》UController
这样也是可以的
现在来一个既有名称也有类型的getBean
现在看一下这三个对象分别是什么
发现是同一个对象
那么spring就是单例模式的
service
service注解和controller一样,都是交给spring来处理的,和controller一样的
Repository,Component,Configuration
看这些注解的原码
知道前面的都是基于Component实现的
这些都是类注解
方法注解bean
比如这个类是第三方的包,我们无法修改之类的,我们如何进行spring的管理呢
这个分别是无参和全参的构造函数注解
这样就可以在spring中管理这个类了
当然也可以在spring中拿到这个对象
可以看出bean找不着
为什么找不到呢
因为bean要配合上面的五大注解来使用,类上面也要注解上,不然没有创建这个类的对象
这样spring才会管理这个对象
才会管理这个方法
才会看到bean
才会进行创建第三方
这样就OK了
但是我们都使用new了,有什么区别吗
区别就是
这个new的在任何地方都可以使用,用Autowired即可
因为已经放在容器里面了
这样干的话就会出错
为什么呢
因为这样的话,就创建了两个bean
但是这里用的类名获取,就会有两个
就会有冲突
我们可以根据名称来
名称就是方法名
@Bean注解,Bean的名称就是方法名
如果一个类有多个对象,就要根据名称,或者类名加名称来获取
类注解一般不会有多个对象
方法注解可能有多个对象
我们还可以对bean进行重命名
一般名字是方法名
在bean注解里面增加name字段就可以了
这个name可以知道,是一个数组,所以可以命名多个
当然五大注解也可以重命名,都是一样的,直接里面加上双引号就可以了
name可以不用写
spring管理的类就是它所在的包下
所以如果启动类放在service文件夹下
那么其余的比如controller就找不到了
那如何扫描其他路径的呢
这个启动类的扫描路径是
com.ck.springioc.service;
那如何改为com.ck.springioc呢
这样就可以了
不然是找不到USerInfo的
而且还可以指定多个扫描路径,就是一个数组
依赖注入
属性注入
Autowired就是属性注入
没有Autowired的话,那么那个类就是null
构造方法注入
可以看出我们加个构造方法就可以了
但是我们加上一个无参的构造方法的话,就又是null了
因为有无参的话,默认使用的是无参的构造方法
如何告诉使用有参的呢
加上Autowired
加上Autowired,默认走的就是这个构造方法
但是Userservie怎么来的呢
我们没有传参啊
构造方法或者普通方法只要有参数
而且对应的对象是spring管理的对象
只有有参数,spring会自己从容器找一个对象来充当这个参数,可以不用传
当然类型是一样的
写这个就可以知道
spring中有一个对象,叫做name,属性为String,值为zhangsan
还有一个对象,就是userInfo2
交给spring管理的对象,如果有参数,这个参数可以自己指定,如果未指定,spring会根据名称或者类型,从容器中查找对象,并注入进来
如果有两个类型的那么
那么有根据名字选择
但是这样就不行了
类型和名称要保持一致
Setter注入
但是这样就不行了,为什么呢
因为构造方法可以在创建的时候自动调用
但是set方法就不行了
但是加上Autowired就可以了
这样就可以了
这个Autowired不可省略
区别
属性注入不能注入final修饰的,而且只能适用于ioc容器
构造函数注入是spring4推荐的
springboot3对应spring6
而且可以注入final
可以注入多个,但是就比较繁琐了
setter是spring3推荐的
不能注入final修饰的
属性注入是程序员推荐
反正都是注入一个userService的对象
有多个对象的时候,名称一个都不对应的时候,就会报错了
因为不知道找哪个,对象只有一个的时候,类型一样还可以勉强找
如何优先选择呢
我们可以用primary注解
这个就是默认的意思,就是不知道选哪个的时候,就选这个
这个是注解默认的bean
我们也可以用Qualifier注解来指定我们想要的bean
这个怎么处理呢
还是一样的方法
法一是
这个启动类这里我们写错了
重新改一下
就没有问题了
然后是第二种方法
其中QUalifier的优先级比Primary高
现在讲一下第三种方式
就是用注解Resource
Resource与Autowired的区别
Autowired是根据类型匹配
Resource是根据名称匹配
但是并不是死的,不一定的也是
类型肯定是第一匹配原则的
Resource与Autowired的基本原则是根据类型匹配
差异就是Resource=Autowired+Qualifier
Resource可以加上name了
Autowired是spring提供的注解
Resource是JDK提供的注解
Autowired不可以指定名称
Resource可以指定名称了
Qualifier的优先级大于变量名
图书管理系统