官网地址:https://spring.io/
概述地址:https://docs.springframework.org.cn/spring-framework/reference/overview.html
太菜了
现在还没有学Maven 先从引入Jar包学起吧
Jar包下下载地址:https://repo.spring.io/libs-release-local/org/springframework/spring/
呕吼 GG 以前收藏的jar包地址打不开了
我把压缩包上传到这里吧 我发现上传后别人如果要下载需要开CSDN VIP 有什么办法能直接分享 可以留言
spring-framework-4.3.10.RELEASE
压缩包解压后 内容说明
是一个概念,是一种思想
控制反转就是对对象控制权的转移,从程序代码本身反转到了外部容器
把对象的创建、初始化、销毁等工作交给spring容器来做
由spring容器控制对象的生命周期
例如:
你想吃包子的话,是不是需要自己去包,相当于自己new了一个对象,这样是不是很麻烦
但是spring容器相当于包子铺,包子铺批量化生产包子,你只需要从包子铺买就可以了,相当于由容器帮你new对象
IOC是一种思想,DI是这种思想的实现方式之一
备注一下:需要提前装好JDK和IDE 就不再演示了哈 网上很多教程
我们跑一下创建好的项目
创建完项目后 需导入jar包 导入jar包的依旧是官方文档
文档地址:https://docs.spring.io/spring-framework/docs/4.3.27.RELEASE/spring-framework-reference/htmlsingle/#spring-introduction
我们可以看到核心容器有4部分
Beans Core Context Expression
项目中新建文件夹 存放jar包
把4个核心jar包拷贝粘贴进去
src目录下新建一个bean类
放一个初始化构造方法
注意哈,Idea自带了很多功能强大的快捷代码,如“sout”、“psvm”、“var”等,通过一个视频演示下
如果不用容器,我们要使用其他对象,是不是需要自己去new呀,就像酱
创建IOC容器
容器就是xml配置文件
创建好的容器是酱
把对象添加到IOC容器
代码实现从容器获取对象
运行报错 原因:缺少一个日志jar包
日志jar包拷到bin目录后 运行正常
代码贴出来
注意啊,getbean的传参就是容器文件中对象的name属性
容器创建对象的原理,就是调用对象的无参构造方法
我们新建一个JavaBean,只添加有参构造方法,不添加无参构造方法,如下
对象添加到IOC容器 可以看到配置文件爆红“No matching constructor found in class ‘Taecher’”
跑一下程序发现报错 报错原因:Teacher类中没有无参构造方法
我们给Teacher类加上无参构造方法
容器配置文件也不再爆红
跑一下程序发现 不再报错
getBean传参用法
我们上面的Demo演示 getBean函数的传参都是容器给赋给对象的“name”,还可以传参“id” “class” 或 “id”、“name”、“class”组合
(1)传参name
(2)传参id
(3)传参class
(4)组合传参
为什么要组合传参?
id相当于人的身份证号 必须唯一 如果2个人身份证号重复了 是不是就有问题
name相当于人的名字 如果2个人名字重复 那我们怎么知道我们要找的是哪个人
class相当于物种 如果你只说你要找人 那么多人你要找谁
因此 容器中每个对象id必须唯一,id重复会报错
因此 容器中每个对象name必须唯一,name重复会报错
因此 容器中为类添加多个对象时,只通过类类型获取bean会报错 找不到唯一的Teacher对象
组合传参 Id+类型组合 获取对象
组合传参 name+类型组合 获取对象
(5)id和name的区别
一个对象只能有一个id,但是可以有多个name
如下,代表注册到容器的这个对象的唯一id为“userId1,userId2,userId3”,这个对象有3个name,分别为“userName1”、“userName2”和“userName3”
按照步骤打开类图解构
(1)从打开的类图解构得知 ApplicationContext 和 BeanFactory都是接口
(2)BeanFactory是ApplicationContext的其中一个父接口,因此,ApplicationContext功能比BeanFactory强大
按照以上步骤我们打开了BeanFacroty接口的实现类XmlBeanFactory的源码
实现类XmlBeanFactory构造函数中传参是一个Resource对象
shift+鼠标左键 点开Resource的源码
点开Resource的源码发现 Resource本身也是一个接口 点击这里查看Resource接口的实现类
找到ClassPathResource后 我们点进去 查看源码知 ClassPathResource初始化时需要传参一个路径
容器配置文件中添加了2个User对象和2个Teacher对象
验证代码
运行结果可以发现
(1)使用ApplicationContext接口初始化容器时,容器中所有对象都会被实例化
(2)而使用BeanFactory接口创建容器时,仅仅只会加载解析容器配置文件,并不会实例化容器中的对象
新建一个package
package中新建工厂类 工厂类添加“生产”对象的静态方法
新建一个容器配置文件 容器配置文件中添加工厂对象
用工厂创建对象
(1)创建静态工厂类
其实例化对象的方法是普通方法
(2)创建容器配置文件 文件中注册 动态工厂类
(3)创建容器对象 容器创建动态工厂对象 动态工厂创建user对象
创建有参构造和重写toString()的代码结构
在配置文件中注册对象时 发现报错 原因:配置文件和有参构造函数不匹配
需要这样修改 在bean内部使用constructor-arg为有参构造函数的3个参数赋值 然后发现爆红就没啦
使用属性name的容器配置文件代码
Demo验证
结果:
上面演示的构造注入 给属性赋值使用的是“name”
还可以使用索引
使用属性索引的容器配置文件代码
结果:
引入c命名空间 然后使用“c:属性名”的简化用法
运行结果:
然后使用“c:索引”的简化用法
运行结果:
设值注入 其实就相当于使用get set方法给属性传值
代码结构:
设值注入的容器配置文件
验证:
同样 设值注入也可以使用简化命名空间 使用p
如果属性类型是自定义对象呢 还能构造注入 传值注入嘛?
新建自定义对象
自定义对象作为其他类的属性
容器配置文件
cat属性是类类型 应该怎么传参呢
如下 先在容器中注册cat对象bean 然后在user对象bean中使用ref赋值
既可以用cat对象bean的id赋值,又可以用cat对象bean的name赋值
验证Demo中使用单元测试注解
首次使用时爆红 使用alt+enter 导入一下依赖
代码
对象注入的容器配置文件等价写法如下:
Demo验证
上面的数据注入 数据类型都是基本数据类型
下面演示非基本类型数据的注入
在容器配置文件中注册大量bean时,配置文件是不是越来越复杂,越来越难用,所以,我们需要引入注解
新建Bean,添加@Component注解
新建容器配置文件,注册扫描路径
测试:
@Component注解用法解释
被该注解标识的java类会被IOC容器加载
如果java的属性是类类型 该如何注入?
我们为User引入Cat类类型属性,创建get和set后,测试发现,返回的cat为null,说明cat并没有被set注入
原因:cat属性缺少注解
修改如下,修改后正常
为什么为User的Cat类型属性标识上@Resource注解后,就无异常了?
我们点开@Resource注解源码可知,默认需要向注解传参一个name值
那我们测试的时候,没有传name,为什么不报错
原因:
那问题又来了,我们并没有给Cat属性起名字“cat”,为什么不报错
原因:
我们点开@Component注解的源码知,需要传一个value值,这个值就是上图中的name,如果不传值,默认就是类名首字母小写
我们给Cat类起注入名cat1
User类中的Cat属性起注入名cat
运行报错:
两者改为一致,即可
上面的@Resource注解是通过name注入,那还有没有别的方案?有的
@Autowired注解+@Qualifier注解的组合来实现注入,@Autowired注解查找扫描路径下的类类型,@Qualifier查找名字
在xml容器配置文件中注册Bean是不是很麻烦
o( ̄︶ ̄)Spring官方肯定能想到
从3.x版本开始,因为配置类的形式,开始舍弃配置文件
新建bean
新建配置类 加上@Configuration注解 此时配置类就相当于是xml配置文件了
配置类中注册bean
主类中通过加载Java配置类得到容器类,然后获取bean对象
运行发现报错 说明UserBean没有注册进Java配置类
这就是涉及到新注解了
加上@Bean注解后 才算是把bean注册进java配置类
查看源码可知,@Bean注解有默认name和value 在我们的案例中,@Bean相当于@Bean(“getUserBean”)
修改运行类的运行参数 正常
如果不想用默认的bean名 可以修改
有很多bean时,不想一个一个往配置类注册 哎 是不是想到了xml配置凡是的扫描注入
添加注解@ComponentScan 用来扫描单个包路径
点进源码 需要传参basePackages
传参basePackages 即bean所在的包路径
为bean加入@Component以供扫描
运行验证
如果要扫描的包路径有多个呢
添加注解@ComponentScans 用来扫描多个包路径
运行验证
如果不想让配置类扫描注册所有bean,需要根据实际的业务来决定呢?要怎麽办?哎 要使用条件注解
查看源码知,需要传参实现Condition接口的实现类
默认返回false so 获取GodBean实例会报错
默认改为true后 获取GodBean实例正常了
如果不想使用默认条件值呢?哎 重写实现类的方法
我们以判断有没有Person类作为判定条件
因为没有Person类,所以运行异常
创建Person类后正常
我们平时开发中 有些代码只允许在生产环境执行 测试环境是不允许执行的 那怎么做?哎 用@Profile注解
测试发现 得到了2个一摸一样的bean实例
为什么?因为默认使用了单例模式
怎么解决?改为多例
实现xml中过滤器相同的功能
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/rfx/64937.html