一篇文带你入门 SSM 框架 Spring 开发!精彩干货不间断!
**反转控制的思想完全颠覆了应用程序组件获取资源的传统方式:反转了资源的获取方向——改由容器主动的将资源推送给需要的组件,开发人员不需要知道容器是如何创建资源对象的,只需要提供接收资源的方式即可,**极大的降低了学习成本,提高了开发的效率。这种行为也称为查找的被动形式。
(2)、DI(Dependency Injection):依赖注入。
说到控制反转,那么就离不开依赖注入,那么什么是依赖注入?**DI 依赖注入是 IOC 的另一种表述方式:即组件以一些预先定义好的方式(例如:setter 方法)接受来自于容器的资源注入。**相对于 IOC 而言,这种表述更直接。
2、SpringIOC 容器的实例化
那么接下来就是如何使用 IOC 容器实现 bean 的配置了,首先我们需要先对 IOC 容器进行实例化,
Spring 提供了 IOC 容器的两种实现方式,分别是:
BeanFactory:IOC 容器的基本实现,是 Spring 内部的基础设施,是面向 Spring 本身的,不是提供给开发人员使用的。
ApplicationContext:BeanFactory 的子接口,提供了更多高级特性。面向 Spring 的使用者,几乎所有场合都使用 ApplicationContext 而不是底层的 BeanFactory。
而 ApplicationContext 接口下面也有两个常用的实现类,分别是:
ClassPathXmlApplicationContext:对应类路径下的 XML 格式的配置文件
FileSystemXmlApplicationContext:对应文件系统中的 XML 格式的配置文
我们在平常的开发中最常用到的应该是 ClassPathXmlApplicationContext 了,
如我们平常获取 IOC 容器的方法是:
ApplicationContext iocContext = new ClassPathXmlApplicationContext("ioc.xml");
3、IOC 容器中添加 bean
在 IOC 容器中配置 bean 的方法也有固定的格式,spring 中规定在容器中添加的 bean 属性需要写在<bean></bean>中,并指明该 bean 的 id 和类路径,如下:
<bean?id="student"?class="com.atguigu.helloworld.bean.Student">
<property?name="studentId"?value="1001"/>
<property?name="stuName"?value="Tom2015"/>
<property?name="age"?value="20"/>
</bean>
三、通过 IOC 容器获取 Bean 属性
=====================
我们现在大概了解到了如果进行 ioc 容器的实例化和获取,那么我们在获取到 ioc 容器之后一般是如何获取其中的 bean 属性的呢?在 spring 中获取 bean 常用的方法是 getBean(),该方法中的参数不同,所表示的含义也不同。
在这里介绍两种在 spring 中常用的获取 bean 的方法,
**1、通过
bean 属性的 id 进行获取**
这种方法需要知道我们所要获取的 bean 在容器中定义的 id,如在 ioc 容器中有如下 bean 的定义:
<bean?id="person01"class="com.spring.beans.Person"></bean>
则通过 bean 的 id 获取这个 bean 属性的方法就是:
ApplicationContext iocContext?= new?ClassPathXmlApplicationContext("ioc.xml");
/**
普通方法获取参数
*/
@Test
public?void?test01() {
Person person01?= (Person)iocContext.getBean("person01");
System.out.println(person01);
}
2、通过 bean 的类型来进行获取
这种方法是在 getBean()中赋于类的 class 进行获取的,方法如下:
ApplicationContext iocContext?= new?ClassPathXmlApplicationContext("ioc.xml");
/**
通过 bean 的类型获取参数
*/
@Test
public?void?test02() {
Person person01?= (Person)iocContext.getBean(Person.class);
System.out.println(person01);
}
有小伙伴可能就问了,要是在 ioc 容器中定义多个同一个类的 bean 属性,那么使用该方法到底该获取哪一个呢?
哎,这就对了!
所以这一种方法只能在 ioc 中只有一个该类型的 bean 时进行获取,否则就会报以下错误:
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.spring.beans.Person] is defined: expected single matching bean but found 4: person01,person03,person04,person05
也就是说,没有找到结果,原因是符合要求的 bean 有多个,不知道该用哪一个了!
那么要是还是想用这一种方法,那该怎么办呢?
接下来就是第三种方法了。
3、通过类和属性名获取参数
这种方法是上面两个方法的结合体,在 getBean()中传入的参数是两个,分别是属性的 id 和 bean 属性的类型,如下:
ApplicationContext iocContext?= new?ClassPathXmlApplicationContext("ioc.xml");
/**
通过类和属性名获取参数
*/
@Test
public?void?test02() {
Person person02 = (Person)iocContext.getBean("person01",Person.class);
System.out.println(person02);
}
以上就是从 ioc 容器中获取 bean 属性的常用方法,
接下来我来和大家聊一下在 IOC 容器中又该如何给 bean 中的属性进行赋值呢?
四、在 IOC 中给 bean 的属性赋值的多种方法
==========================
现在我们已经知道了如何在容器中添加需要的 bean 了,那么接下来就是如何对这些 bean 进行赋值的问题,针对 bean 中属性的类型不同,spring 中有多种为 bean 中属性赋值的方法。接下来我们对这几种方法一一介绍。
1、通过无参构造并指定属性赋值
首先第一种方法,也是最普通常用的一种方法,就是利用 bean 中属性的 set 方法进行赋值,这种方法对属性的赋值语句需要写了<bean></bean>的<property></property>中,
<bean?id="person01"?class="com.spring.beans.Person">
<property?name="name" value="张三"></property>
<property?name="age"?value="18"></property>
<property?name="sex"?value="男"></property>
<property?name="email"?value="133@qq.com"></property>
</bean>
其中的 name 中的参数是你在 bean 中定义的属性名,value 是你将要赋予的属性值,
2、通过有参构造并指定属性进行赋值
上面那种方法指定在 bean 没有有参构造器的情况下进行属性的赋值的方法,那么现在这种方法就是,当 bean 中存在有参构造器时使用的赋值方法,当然,当 bean 中同时存在有参构造和无参构造器时,上面那种方法还可以使用!
通过有参构造器进行赋值使用的并不是<property></property>,而是在<constructor-arg></constructor-arg>中,其中的参数 name 和 value 与上面的含义一样。
<bean?id="person03"?class="com.spring.beans.Person">
<constructor-arg?name="name"?value="小明"></constructor-arg>
<constructor-arg?name="sex"?value="男"></constructor-arg>
<constructor-arg?name="age"?value="30"></constructor-arg>
<constructor-arg?name="email"?value="xioaming@136.com"></constructor-arg>
</bean>
3、通过有参构造不指定属性进行赋值
第二种方法介绍了使用有参构造指定属性进行赋值,但是有小伙伴们就该说了,那这不是和第一种方法使用差不多嘛,哎,那我们现在再来看一种方法。利用有参构造不指定属性进行赋值,也就是说不使用 name 了,直接使用 value 进行赋值。比如我们的 bean 中的有参构造器长这样:
public?Person(String name, int?age, String sex, String email) {
super();
this.name?= name;
this.age?= age;
this.sex?= sex;
this.email?= email;
}
那么通过有参构造不指定属性进行赋值时,就需要将赋值元素书写的顺序按照有参构造器中元素属性的顺序进行书写了
<bean?id="person04"?class="com.spring.beans.Person">
<constructor-arg?value="小刚"></constructor-arg>
<constructor-arg?value="20"></constructor-arg>
<constructor-arg?value="男"></constructor-arg>
<constructor-arg?value="xiaogang@qq.com"></constructor-arg>
</bean>
在这里有一点需要注意:
就是如果两个有参构造器属于重载,那么在 ioc 中进行赋值时就需要使用 type 在 value 的后面指明赋值的元素的属性,比如是 string 还是 int 型的。
关于 type 的使用我们看下面的方法!
4、通过索引值指定参数的位置
当我们在使用有参构造器不指定属性赋值时,还有另外的方法,可以不必须的按照顺序来书写赋值。那就是使用索引和属性类型了,**使用索引进行赋值时需要使用到 index 参数,指定要赋值的属性的序号,**如对于上面 person 的构造函数,使用 index 指定元素位置进行赋值。name 的 index 是 0,age 是 1.
<bean?id="person04"?class="com.spring.beans.Person">
<constructor-arg?value="20"?index=”1”></constructor-arg>
<constructor-arg?value="小刚"?index=”0”></constructor-arg>
<constructor-arg?value="xiaogang@qq.com"?index=”3”></constructor-arg>
<constructor-arg?value="男"?index=”2”></constructor-arg>
</bean>
按照上面的方式同样可以得到相同的赋值效果
5、通过类型不同区分重载的构造器
如我们现在有两个同名的有参构造器,但是其中参数类型不一样,如果我们依然使用上面的两种方法来对 bean 中的属性进行赋值,那么明显是会报错提示构造器不唯一的。
所以这个时候就需要使用 type 指定参数的类型,同时 index 和 type 可以结合使用,如下:
<bean?id="book"?class="com.atguigu.spring.bean.Book"?>
<constructor-arg?value=?"10010"?index?="0"?type="java.lang.Integer"?/>
<constructor-arg?value=?"Book01"?index?="1"?type="java.lang.String"?/>
<constructor-arg?value=?"Author01"?index?="2"?type="java.lang.String"?/>
<constructor-arg?value=?"20.2"?index?="3"?type="java.lang.Double"?/>
</bean?>
6、利用 P 名称空间进行赋值
下面我们来介绍一个全新的赋值方式,利用 P 名称空间进行赋值。
为了简化 XML 文件的配置,越来越多的 XML 文件采用属性而非子元素配置信息。Spring 从 2.5 版本开始引入了一个新的 p 命名空间,可以通过<bean>元素属性的方式配置 Bean 的属性。
使用 p 命名空间后,基于 XML 的配置方式将进一步简化。具体使用如下,
首先我们应该在 xml 文件中加入 P 名称空间的使用插件。
加入 P 名称空间的使用插件的方法如下:以 eclipse 为例:
评论