一、什么是IOC
注释:前面的内容都是概念性和常用内容的介绍,写在前面是为了之后方便查阅,请结合后面的具体实例学习,前面的内容供之后查阅使用
-
IOC(Inversion of Control)反转控制
- IOC是一种思想,将对象交给一个容器帮我们管理,用户只需在需要时向容器要就行。而传统的对象需要我们根据类模板去自己创建出来,自己管理
- 反转控制颠覆了传统的new形式创建对象,spring的IOC容器会在容器加载时利用反射创造对象
- 因为是反射,所以要反射的类一定要有无参构造器,所以当我们为类中添加了有参构造器,一定要补充一个无参的,然后类中的成员变量也一定要有set和get方法,spring为属性赋值时,会找set方法去掉set3个字母后面的名字进行赋值
- 用户无需在意建立对象,专心接收资源即可,只需将所需要的对象配置在spring的配置xml文件中或者使用注解标识即可创建出对象,然后在需要的时候获取即可,而且这些对象一旦创建,则一直是它自己一个,不会出现多个浪费空间,也就是单例设计模式
-
DI(Dependency Injection)依赖注入
- 是IOC思想的实现技术,组件(对象)会以预先定义好的方式在容器注入,使用配置文件将对象反射到IOC容器中
- IOC是一种思想而DI是对IOC的一种实现
-
Bean获取的方式
- getBean(“id”); 通过容器中的id值获取对象,但获取的对象,无法确定类型,需要强制转换
- getBean(ClassName.class):通过指定类型去获取容器中相应类型的Bean,好处:不用强制转换,缺点:若有多个同类型,会报错
- getBean(“id”,ClassName.class):结合前面两种方式,有唯一标识,解决有多个同类型Bean时的冲突问题,同时也解决无法确定类型需要强制转换的问题
- @Autowired:注解形式直接获取对象
-
DI依赖注入为Bean的属性赋值
- 对spring容器来讲set方法后面的名字才是属性名,而非成员变量本身
- spring就是通过调用set方法为属性赋值的
二、DI依赖注入
-
什么是DI依赖注入
- 就是通过一些配置和注解将组件(对象)注入到IOC容器中的技术
- 对于DI依赖注入的讲解都会根据上一节:spring的HelloWorld基础上进行讲解,若还没有搭建请参考上一节课程https://blog.csdn.net/grd_java/article/details/104697546
-
将对象注入到IOC容器并为属性赋值
-
1、注入对象并通过set方法赋值
-
创建工程
1、User类只创建一个id成员变量,并为其设置get和set方法,和toSpring方法,这里它会默认带一个无参构造
2、将对象注入到容器并为属性赋值,这里bean标签作用就是创建一个对象,id属性相当于给这个实例起的名字,class指定要创建类的全类名(就是告诉IOC创建的是哪一个类的实例,要准确到包名)property标签表示为这个对象的属性赋值,调用的是当前类中的set方法,name属性表示调用哪一个set方法,我们这里写的id表示调用setId()方法,value属性表示要传的值,这里传001,整个连起来的意思就是:
创建一个User类实例起名为user并调用setId()方法将001作为参数传递,然后执行方法体this.id=id,将001这个值赋值给私有的成员变量id(这是我自己看源码和实验得出的结论,大家可以自己测试,通过将User类的setId方法改成setId2,可以发现xml文件中name属性也要改成id2,以上是自己的结论,若有错误,请留言指出)。
3、测试,通过xml创建ApplicationContext接口对象,调用getBean方法获取组件(容器中配置好的对象)最终通过输出语句输出,因为重写了toString方法,所以直接输出对象时,会按重写的toString风格输出
-
-
-
2、通过构造方法赋值
-
注意,ioc容器在反射对象时,是通过无参构造器反射的,所以无论何时,实体类中一定要保证有一个无参构造器,比如我们为User类添加一个有参构造器,试图以构造方法的方式注入到容器中,这时就会报错,因为当我们为一个类添加了一个构造器,默认无参的就不提供了,所有一定要手动吧无参构造器加上
-
构建工程
1、为User类添加有参构造器,并补充无参构造器
2、先bean一个User类实例起名user添加到IOC容器中,然后通过constructor-arg标签为构造方法的参数赋值,一个标签代表一个参数,若有两个参数就添加两个constructor-arg标签,按声明顺序赋值, - value属性:表示要传递的值
- index属性:当我们不是按照顺序赋值时就会报错,这时可以通过指定index属性表示这个值是给构造方法第几个参数传的,下标从0开始
- type属性:指定当前参数类型,当构造方法重载时,就需要确定类型才能匹配到正确的方法,这时指定类型即可。类型要写全类名例如:java.lang.Integer
3、测试和set方法获取bean一样
-
-
3、通过p命名空间赋值
-
如何开启p命名空间
先打开我们spring配置文件,然后在下方进入Namespaces选项卡,勾选p命名空间
-
4、引用赋值
-
4、使用内部Bean实现赋值
-
4、级联赋值
-
5、赋空值
只需使用功能null标签即可
-
5、集合赋值
-
List集合
1、这里为Car类定义一个List接口变量carNames
2、注入到容器中为List集合赋值并测试
-
数组
可以和List一样用list标签赋值或通过array标签来赋值
-
set集合
和LIst完全一样,就是关键字不一样而已
-
Map集合
map标签中定义了3个entry标签,表示3个键值对,key依次是1,2,3。value依次是引用其他对象的引用类型,内部Bean,基本数据类型
-
可供引用的公有集合Bean
1、打开util命名空间
2、定义公有集合并测试
通过指定<util:需要的集合类型>标签,即可设置一个可引用的公有集合,编写内容和普通形式一样,最后为其指定id名,在需要的地方使用ref引用id即可
-
-
FactoryBean,使用工厂创建对象
很多时候我们需要使用功能工厂设计模式创建对象,具体配置如图所示。
这里的3个方法都是重写FactoryBean接口的,其中getObject方法是最终返回我们需要创建的对象的方法,我们通过new的方式返回,这里因为只有无参构造,所以这个对象创建出来,所以属性都是null
然后只需要通过工厂类注入对象即可
-
Bean之间的继承
看图即可
-
Bean的依赖
就是指定若想创建某对象必须先确定存在某一对象的
-