注意:
下面的词汇同时涉及到专业词、程序的自定义词。建议先阅读程序(有看得懂代码结构的基础就行) 我会把程序发出来,并附上使用视频
用于配置对象交由Spring来创建。默认情况下它调用的是类中的无参构造函数,如果没有无参构造函数则不能创建成功。这个无参构造就是你在 bean标签里面的class属性值里面写的路径的实现类必须要有无参构造方法
基本属性:
1、id: Bean实例在Spring容器中的唯一标识。也就是bean标签是唯一性标识,也就意味着bean标签里面的'id属性的值'不能重复
2、class: Bean的全限定名称。也就是bean标签里面的'class属性的值'是全限定名称
scope: 指对象的作用范围。这个scope属性也是写在Bean标签里面的,如果不写scope属性,就默认是singleton。scope属性的取值如下:
取值范围 | 说明 |
---|---|
singleton | 默认,单例的 |
prototype | 多例的 |
request | WEB项目中,Spring创建一个Bean的对象,将对象存入到request域中 |
session | WEB项目中,Spring创建一个Bean的对象,将对象存入到session域中 |
global session | WEB项目中,应用在Portlet环境,如果没有Portlet环境那么globalSession相当于session |
我们主要记住singleton、prototype
当scope的取值为singleton时
1、Bean的实例化个数: 1个
2、Bean的实例化时机: 当Spring核心文件被加载时,实例化配置的Bean实例
3、Bean的生命周期: (1)对象创建: 当应用加载,创建容器时,对象就被创建了 (2)对象运行: 只要容器在,对象一直活着 (3)对象销毁: 当应用被卸载,或者销毁容器时,对象就被销毁了
当scope的取值为prototype时
1、Bean的实例化个数: 多个
2、Bean的实例化时机: 当调用getBean()方法时,实例化配置的Bean实例
3、Bean的生命周期: (1)对象创建: 当使用对象时,创建新的对象实例 (2)对象运行: 只要对象在使用中,就一直活着 (3)对象销毁: 当对象长时间不用时,被Java的垃圾回收机器回收了
涉及到两个属性,也就是我们在bean标签里面可写的属性,有两个控制生命周期的属性。可同时写两个属性。如下
1、init-method: 指定类中的初始化方法名称
2、destroy-method: 指定类中销毁方法名称
例如:
<bean id="userDao" class="com.huanf.dao.impl.UserDaoImpl" scope="singleton" init-method="init" destroy-method="destroy"></bean>
我们最上面讲过'bean标签里面的class属性值里面写的路径的实现类必须要有无参构造方法',那么我们能不能在没有无参构造的情况下,也正常使用呢, 下面就来学通过配置来实现
第一种: 无参构造方法实例化(默认) 第二种: 工厂静态方法实例化 第三种: 工厂实例方法实例化
第一种就是我们前面一直用的,我们这里不多介绍,只介绍第二种、第三种
问题: 对象在执行的时候被创建了两次,也就是一个功能加载了配置文件两次。解决: 学习下面的Bean的依赖注入分析,然后我们再解决
目前UserService实例和UserDao实例都存在于Spring容器中,当前的做法是在容器外部获得UserService实例和UserDao实例,然后在程序中进行结合,问题如下
1、Spring容器的UserService实例(对象): 负责我们程序代码中的 'getBean(name:"userService")'。这段代码的意思是: 获得UserService实例,发现UserService实 例内部需要UserDao实例的save()方法,所以在UserService内部获得UserDao实例
2、Spring容器的UserDao实例: 负责我们程序代码中的 'getBean(name:"userDao")'。这段代码的意思是: 相当于是在Spring容器外将Dao组装到Service内 部完成的操作
解决: 我们的UserService实例真正用的是UserService,而不需要关心UserDao是怎么获取的,我们可以直接在容器内部就获取UserDao,而 不是在 'UserService内部获得UserDao实例' 。就可以解决UserService实例被创建两次的问题
思路: 因为UserService和UserDao都在Spring容器中,而最终程序直接使用的是UserService,所以可以在Spring容器中,将UserDao设置到UserService内部,解决如下
1、Spring容器的UserService实例: 负责我们程序代码中的 'getBean(name:"userService")'。这段代码的意思是: 获得UserService实例,内部已经存 在UserDao实例了,直接调用UserDao的save()方法即可
2、Spring容器的UserDao实例: 直接拿UserService实例内部的UserDao实例
上面我们的分析+解决,就是使用了依赖注入。依赖注入(Dependency Injection): 是Spring框架核心IOC的具体体现。在编写程序时,通过控制反转,把对象的 创建权交给了Spring,但是代码中不可能出现没有依赖的情况,IOC解耦只是降低他们的依赖关系,但并不会消除。例如: 业务层面仍会调用持久层的方法。那 这种业务层和持久层的依赖关系,在使用Spring之后,就让Spring来维护了。简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取
怎么将UserDao注入到UserService内部呢?有两种方式,如下
1、构造方法(有参构造注入)
2、set方法。其中又分两种 (1) 在程序里,'UserServiceImpl'、'applicationContext.xml' 进行配置。 (2) P命名空间注入。本质也是set方法注入,但比起上述的set方法注入更加方便,主要体现在配置文件中,如下
//首先,在 'applicationContext.xml' 的最上面的bean标签里,需要引入p命名空间
xmlns:p="http://www.springframework.org/schema/p"
//其次,在 'applicationContext.xml' 的最下面你在用的bean标签里,需要修改注入方式 <bean id="userService" class="com.huanf.service.impl.UserServiceImpl" p:userDao-ref=""userDao"/>
上面的set、p、有参,演示的都是注入'对象引用'(我们一直在用ref),那可不可以注入普通数据类型或者集合, 其实普通数据类型(用value)或者集合(用property标签里面的子标签)都可以在容器中进行注入
注入数据的三种数据类型
1、普通数据类型
2、引用数据类型
3、集合数据类型
使用场景: 由于长期对一个applicationContext.xml文件进行配置,会使得代码量很庞大,导致applicationContext.xml文件可读性差,也不方便维护。 解决: 我们可以对applicationContext.xml文件进行拆解,可以按照业务模块(用户模块、商品模块)、层(dao层、业务层)来拆解
实际开发中,Spring的配置内容非常多,这就导致Spring配置很繁杂且体积很大,所以,可以将部分配置拆解到其他配置文件中,而 在Spring主配置文件通过import标签进行加载。在主配置文件applicationContext.xml中引入其他分配置文件。在主配置文件添加如下
<import resource="applicationContext-xxx.xml"/>
xxxxxxxxxx
<bean>标签
id属性: 在容器中Bean实例的唯一标识,不允许重复
class属性: 要实例化的Bean的全限定名,也就是路径
scope属性: Bean的作用范围,常用是Singleton(默认,表示单例)和prototype(表示多例)
<property>标签: 属性注入
name属性: 属性名称
value属性: 注入的普通属性值
ref属性: 注入的对象引用值
<list>标签