目录
1、SpringDI(依赖注入)
(1)Spring DI的理解
DI(Dependecy Inject,中文释义:依赖注入)是对IOC概念的不同角度的描述,是指应用程序在运行时,每一个bean对象都依赖IOC容器注入当前bean对象所需要的另外一个bean对象。(例如在MyBatis整合Spring时,SqlSessionFactoryBean依赖IOC容器注入一个Datasource数据源bean );
(2)SpringDI的作用
将SpringIOC容器所创建的各个组件,使用DI的语法进行关联,耦合(胶水)减少耦合。
(3)什么是Spring的bean
<bean>标签是Spring XML配置文件中最基本的构建块,用于定义Spring容器中的Bean。
简单来说,Bean代表被IOC容器管理的对象,我们通过配置文件或注解,告诉IOC容器帮助我们管理哪些对象。
<bean id="..." class="...">
<constructor-arg value="..."/>
</bean>
(4)DI实现方式
Spring2.5版本:在resources中添加.xml工具类在里面实现注入。
set注入:
关键词<proprety>
<bean id="controllerImp" class="com.apesource.controller.UserControllerImp">
<property name="service" ref="serviceImp"></property>
</bean>
id代表的是这个Bean的唯一标识符,在Spring容器中,你可以通过这个ID来引用和获取这个Bean。相当于可以通过这个id名来获取相应的bean。
class代表的是指定的Bean的实现类,用这个实现类来完成里面的相对应的逻辑。
<property>标签:
name属性指定了要注入的Bean的属性名。比如在这个UserControllerImp有一个名为service的属性,这个属性将被注入依赖例如下面的代码,其中的service就被注入依赖了。
public UserControllerImp(IUserService service) {
this.service = service;
}
ref属性指定了要注入的Bean的ID,在这种情况下,serviceImp是另一个serviceImp实现类的ID,Spring会将ID为serviceImp的Bean注入到controllerImp的service属性中。也就是通过一个类去注入自己的属性。
set注入基本类型与String:
<bean id="student" class="com.apesource.pojo.Student">
<property name="stuName" value="张文英"></property>
<property name="stuAge" value="18"></property>
<property name="stuHobby" value="学习"></property>
</bean>
其中的value为对这个name中的属性所附的值,注入进去。
set注入基本类型与复杂类型:
(单列):
与list列表的注入:
<property name="myList">
<list>
<value>老米家泡馍</value>
<value>红红炒米</value>
<value>马昆砂锅</value>
<value>石家包子</value>
</list>
</property>
与array数组的注入:
<property name="array">
<array>
<value>游戏</value>
<value>跑步</value>
<value>谈恋爱</value>
<value>学习</value>
</array>
</property>
与set集合的注入:
<property name="mySet">
<set>
<value>茶话弄</value>
<value>茶百道</value>
<value>蜜雪冰城</value>
<value>霸王茶姬</value>
<value>茉莉奶绿</value>
</set>
</property>
(多列):
与map集合的注入:
<property name="myMap">
<map>
<entry key="杨文琦" value="心动"></entry>
<entry key="贺佳瑶" value="小贺"></entry>
<entry key="张甜甜" value="小猪佩奇"></entry>
<entry key="林航宇" value="林"></entry>
</map>
</property>
与property的注入:
<property name="myProp">
<props>
<prop key="法国">巴黎</prop>
<prop key="英国">伦敦</prop>
<prop key="日本">东京</prop>
<prop key="美国">华盛顿</prop>
<prop key="俄罗斯">乌克兰</prop>
</props>
</property>
构造注入:
关键词:<constructor-arg> 这是Spring配置文件中的一个标签,用于指定一个构造函数的参数。name:这个对应的是属性名称,value是注入的值。
注入控制器:
<bean id="controllerImp2" class="com.apesource.controller.UserControllerImp">
<constructor-arg name="service" ref="serviceImp2"></constructor-arg>
</bean>
ref对应的是从哪个bean中来注入该属性的对象。
2、SpringIOC容器对Bean管理
(1)bean实例化
<1> 通过构造方法(默认)
<bean id="student" class="com.apesource.pojo.Student">
id指的是该bean实例的标识符,class指的是bean对应的java类,实例化哪个类。
<2> 通过普通工厂方法
<bean id="student" class="com.apesource.pojo.Student" factory-bean="factory" factory-method="createStu"></bean>
<bean id="factory" class="com.apesource.factory.BeansFactory"></bean>
factory工具包下的BeansFactory类:
public class BeansFactory {
public Student createStu(){
System.out.println("===>执行普通工厂");
return new Student();
}
}
factory-bean:指定一个 Spring 容器中已经定义的 bean,这个 bean 用作工厂来创建其他 bean 实例。
factory-method:指定工厂 bean 中的方法,这个方法用于创建目标 bean 实例。
<3> 通过静态工厂方法
<bean id="student" class="com.apesource.factory.StaticBeansFactory" factory-method="createStu"></bean>
factory工具包下的StaticBeansFactory类:
public class StaticBeansFactory {
public static Student createStu(){
System.out.println("===> 执行static工厂");
return new Student();
}
}
(2)bean作用域
含义:spring对于创建javaBean实例的方式。
语法:<bean scope="属性值"></bean>
属性值:
singleton | 单例(默认) |
prototype | 多例 |
request | 一个请求创建一个 |
session | 一个会话创建一个 |
Spring提供了几种常用的作用域:
- Singleton(默认作用域):每个 Spring IoC 容器中只有一个 bean 实例。所有对这个 bean 的请求都会返回同一个实例。
- Prototype:每次请求都会创建一个新的 bean 实例。
- Request:在 Web 应用中,每个 HTTP 请求都会创建一个新的 bean 实例。这个作用域仅在 web 环境中有效。
- Session:在 Web 应用中,每个 HTTP 会话(Session)都会创建一个新的 bean 实例。这个作用域仅在 web 环境中有效。
- GlobalSession:在多个 HTTP 会话共享的情况下,每个全局 HTTP 会话都会创建一个新的 bean 实例。这个作用域仅在 Portlet 环境中有效。
示例代码:
<bean id="teacher" class="com.apesource.pojo.Teacher" scope="prototype"></bean>
scope 属性定义了 bean 的作用域,也就是 bean 实例的生命周期和创建方式。
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// 在单例情况下,teacher1 和 teacher2 是同一个实例,所以 teacher1 == teacher2 返回 true。
// 在多例情况下,teacher1 和 teacher2 是不同的实例,所以 teacher1 == teacher2 返回 false。
Teacher teacher1 = (Teacher) applicationContext.getBean("teacher");
Teacher teacher2 = (Teacher) applicationContext.getBean("teacher");
System.out.println(teacher1==teacher2);
(3)bean生命周期
- 实例化
- 属性赋值(DI)
- 初始化 接口 InitializingBean / 属性 init-method=""
- 操作使用
- 销毁了 接口 DisposableBean / 属性 destory-method=""
<bean id="user" class="com.apesource.pojo.User" init-method="doinit" destroy-method="doDestory">
<property name="uname" value="杨文琦"></property>
</bean>
init-method:指定 bean 在初始化要调用的方法。
destroy-method:指定 bean 在销毁时要调用的方法。