Spring 学习笔记
第一章 Spring基础概念
一.反向控制/依赖注入
IOC (Inversion of Control)
二.依赖注入的3种实现方式:
1.接口注入 (interface injection)
接口注入指的就是在接口中定义要注入的信息,并通过接口完成注入。
2.Set注入 (setter injection)
Set注入指的就是在接受注入的类中定义一个 Set 方法,并在参数中定义需要注入的元素。
<bean id="" class="">
<!--属性msg 的Set注入-->
<property name="msg">
<value>propertyvalue</value>
</property>
</bean>
<!--属性msg 的Set注入-->
<property name="msg">
<value>propertyvalue</value>
</property>
</bean>
3.构造注入 (constructor injection)
构造注入指的就是在接受注入的类中定义一个构造方法,并在参数中定义需要注入的元素。
<!--通过构造注入的Bean-->
<bean id="" class="">
<!--为构造函数的第一个参数进行注入,可以为多个参数指定注入,只要更改 index-->
<constructor-arg index="0">
<value>propertyvalue</value>
</constructor-arg>
</bean>
<!--为构造函数的第一个参数进行注入,可以为多个参数指定注入,只要更改 index-->
<constructor-arg index="0">
<value>propertyvalue</value>
</constructor-arg>
</bean>
总结:使用哪一种注入方式更好一点?我建议使用 Set 注入。因为这样最方便。
如果使用构造注入的话,您必须非常清楚参数的位置。
注意:使用 Set 注入,属性一定要有 Setter 方法。
第二章 Spring 的核心容器
一.Bean 的标识 (id 和 name)
1.在 Spring 中可以用 id 或者 name 属性来指定 Bean 的 id,并且在这两个或其中一个属
性中至少指定一个 id。
2.id 和 name 区别:
id 属性允许指定一个 Bean 的 id,并且它在 XML DTD 中作为一个真正的 XML 元素的ID属性
被标记,所以 XML 解析器能够在其他元素指向它的时候做一些额外的校验,但是,XML 规范
严格限定了在 XML ID 中合法的字符。如果在开发中有必要使用一些非法的字符,即不符合 ID
规定的字符,或者要给 Bean 增加其他的别名,则可以通过 name 属性指定一个或多个 id。
当指定多个 id 时要用逗号或才分号分隔。
二.在 Spring 中,Bean 可以被定义为两种部署模式中的一种:singleton 或 non-singleton.Spring
默认为 singleton 模式。
1.如果一个 Bean 被定义为 singleton 模式,那么就只有一个共享的实例存在,所有对这个 Bean
的请求都会返回这个唯一的实例。
<bean id="" name="" class="">
<!--Spring默认为singleton模式-->
<property name="msg" singleton="true">
<value>propertyvalue</value>
</property>
</bean>
<!--Spring默认为singleton模式-->
<property name="msg" singleton="true">
<value>propertyvalue</value>
</property>
</bean>
2.如果一个 Bean 被定义为 non-singleton 模式,那么对这个 Bean 的每次请求都会创建一个
新的 Bean 实例,您可以把它当成类似new的操作。
<!--使用 non-singleton 每调用一次将实例化一 Bean 对象-->
<bean id="" name="" class="" singleton="false">
<property name="msg" singleton="true">
<value>propertyvalue</value>
</property>
</bean>
<bean id="" name="" class="" singleton="false">
<property name="msg" singleton="true">
<value>propertyvalue</value>
</property>
</bean>
三.Bean 的属性
1.ref 属性
<bean id="" name="" class="">
<property name="date">
<ref bean="date"/>
<!--或者使用-->
<bean id="date" class="java.util.Date"/>
</property>
<!--或者使用-->
<property name="date" ref="date"/>
</bean>
<bean id="date" class="java.util.Date"/>
<property name="date">
<ref bean="date"/>
<!--或者使用-->
<bean id="date" class="java.util.Date"/>
</property>
<!--或者使用-->
<property name="date" ref="date"/>
</bean>
<bean id="date" class="java.util.Date"/>
2.对于 null 值的处理
<bean id="" class="">
<property name="msg">
<value>null</value>
<!--或者使用-->
<null/>
</property>
</bean>
<property name="msg">
<value>null</value>
<!--或者使用-->
<null/>
</property>
</bean>
四.使用依赖 depends-on
Bean 的 depends-on 属性可以用来在初始化使用这个 Bean 之前,强制执行一个或多个 Bean 的初始化。
<bean id="" class="">
<property name="msg">
<value>msgvalue</value>
</property>
<property name="date">
<ref bean="date"/>
</property>
</bean>
<property name="msg">
<value>msgvalue</value>
</property>
<property name="date">
<ref bean="date"/>
</property>
</bean>
五.Bean 的生命周期
1.Bean 的定义,在 Spring 中通常是通过配置文档的方式来定义 Bean 的。
2.Bean 的初始化,Bean 的初始化有两种方式:
。.在配置中通过指定 init-method 属性来完成。
<!--init是 Bean 本身的一个初始化方法,为 Bean 本身的属性赋值-->
<bean id="" class="" init-method="init"/>
<bean id="" class="" init-method="init"/>
。。.实现 org.springframework.beans.factory.InitializingBean 接口,实现此接品后
则它的所有必需的属性被 BeanFactory 设置后,会自动执行它的 afterPropertiseSet()方法。
3.Bean 的使用:在 Spring 中 Bean 的使用有 3 种方式。
第一种:使用 BeanWrapper.
HelloWorld hello = new HelloWorld();
BeanWrapper bw = new BeanWrapperImpl(hello);
bw.setPropertyValue("msg","HelloWorld"); //赋值
BeanWrapper bw = new BeanWrapperImpl(hello);
bw.setPropertyValue("msg","HelloWorld"); //赋值
第二种:使用 BeanFactory.
InputStream is = new FileInputStream("config.xml");
XmlBeanFactory factory = new XmlBeanFactory(is);
HelloWorld hello = (HelloWorld)factory.getBean("helloworld");
XmlBeanFactory factory = new XmlBeanFactory(is);
HelloWorld hello = (HelloWorld)factory.getBean("helloworld");
第三种:使用 ApplicationContext.
ApplicationContext actx = new FileSystemXmlApplicationContext("config.xml");
HelloWorld hello = (HelloWorld)actx.getBean("helloworld");
HelloWorld hello = (HelloWorld)actx.getBean("helloworld");
4.Bean 的销毁:在 Spring 中,Bean 的销毁有以下两种方式。
第一种:在配置文档中通过指定 destroy-method 属性来完成。
<bean id="" class="" destroy-method="cleanup"/>
第二种:实现 org.springframework.beans.factory.DisposableBean 接口,则会自动执行它的 destroy()方法。
六.用 ref 的属性指定依赖的 3 种模式
1.用 local 属性指定:如果一个 Bean 民被参生引用的 Bean 在同一个 XML 文件中而且被参考引用
的 Bean 是用 id 来命名的,那么就可以使用 ref 的 local 属性。
<bean id="" class="">
<property name="">
<!--local 属性的值必须与被参考引用的 Bean 的 id 属性一致-->
<ref local=""/>
</property>
</bean>
<property name="">
<!--local 属性的值必须与被参考引用的 Bean 的 id 属性一致-->
<ref local=""/>
</property>
</bean>
2.用 ref 元素的 Bean 属性指定被参考引用的 Bean 是 Spring 中最常见的形式,它允许指向的
Bean 可以在同一个 XML 中,也可以不在同一个 XML 中。
<bean id="" class="">
<property name="date">
<!--此 date 在本 XML 或别的 XML 文档中一定要存在-->
<ref bean="date"/>
</property>
</bean>
<property name="date">
<!--此 date 在本 XML 或别的 XML 文档中一定要存在-->
<ref bean="date"/>
</property>
</bean>
3.用 parent 属性指定:parent 属性的值可以与被参考引用的 Bean 的 id 属性相同,也可以与被参考引用 Bean 的 name 属性相同。
<bean id="" class="">
<property name="date">
<ref parent="date"/>
</property>
</bean>
<property name="date">
<ref parent="date"/>
</property>
</bean>
总结:3 种模式中 local 和 bean 是最常用的,下面对这两种模式进行比较。
相同之处:都可以用 Bean 的 id 来进行参考引用,都可以对同一 XML 中的 Bean 进行参考引用。
不同之处:用 bean 属性指定依赖可以用 Bean 的 name 来进行参考引用,还可以对不同 XML 中的 Bean 进行参考引用。
七.Bean 自动装配的 5 种模式
1.使用 byName 模式:byName 模式指的就是通过 Bean 的属性名字进行自动装配。在 Spring 的配置文档 XML 中,
查找一个与将在装配的属性同样名字的 Bean.
public class HelloWorld{
private String msg;
private Date date; //在配置中将自动装载
}
private String msg;
private Date date; //在配置中将自动装载
}
//配置
<bean id="" class="" autowire="byName">
<property name="msg">
<value>msgvalue</value>
</property>
</bean>
<bean id="date" class="java.util.Date"/>
<property name="msg">
<value>msgvalue</value>
</property>
</bean>
<bean id="date" class="java.util.Date"/>
2.使用 byTpe 模式:如果 XML 中正好有一个与属性类型一样的 Bean ,就自动装配这个属性。如果有多于一个这样的 Bean ,
就抛出一个异常。
3.使用 constructor 模式:根据构造函数的参数进行自动装配。
public class HelloWorld{
private String msg;
private Date date;
public HelloWorld(Date date){} //根据构造函数的参数进行装配
}
private String msg;
private Date date;
public HelloWorld(Date date){} //根据构造函数的参数进行装配
}
//配置
<bean id="" class="" autowire="constructor">
<property name="msg">
<value>msgvalue</value>
</property>
</bean>
<!--此 date 要与要构造函数中参数的名保持一致-->
<bean id="date" class="java.util.Date"/>
<property name="msg">
<value>msgvalue</value>
</property>
</bean>
<!--此 date 要与要构造函数中参数的名保持一致-->
<bean id="date" class="java.util.Date"/>
4.使用 autodetect 模式:通过对 Bean 检查类的内部来选择使用 constructor 或 byType。
<bean id="" class="" autowire="autodetect">
<property name="msg">
<value>msgvalue</value>
</property>
</bean>
<bean id="date" class="java.util.Date"/>
<property name="msg">
<value>msgvalue</value>
</property>
</bean>
<bean id="date" class="java.util.Date"/>
5.使用 no 模式:就是一使用自动装配。
总结:大型应用中不鼓励使用自动装配,因为它去除了参考依赖的透明性和清晰性。
八.Bean 依赖检查的 4 种模式
为什么使用依赖检查:因为如果我们不使用自动装配,就很有可能会出现某个属性未赋值。
1.使用 simple 模式:对基本类型、字符串和集合进行依赖检查。
<bean id="" class="" autowire="autodetect" dependency-check="simple">
<property name="msg">
<value>msgvalue</value>
</property>
</bean>
<property name="msg">
<value>msgvalue</value>
</property>
</bean>
2.使用 object 模式:对依赖的对象进行依赖检查。
<bean id="" class="" autowire="autodetect" dependency-check="object">
<property name="msg">
<value>msgvalue</value>
</property>
</bean>
<property name="msg">
<value>msgvalue</value>
</property>
</bean>
3.使用 all 模式:对全部属性进行依赖检查。
<bean id="" class="" autowire="autodetect" dependency-check="all">
<property name="msg">
<value>msgvalue</value>
</property>
</bean>
<property name="msg">
<value>msgvalue</value>
</property>
</bean>
4.使用 none 模式:不进行依赖检查。
<bean id="" class="" autowire="autodetect" dependency-check="none">
<property name="msg">
<value>msgvalue</value>
</property>
</bean>
<property name="msg">
<value>msgvalue</value>
</property>
</bean>
九.集合的注入方式
1.List 的注入
<bean id="" class="">
<property name="sutdents">
<list>
<value>jek1</value>
<value>jek2</value>
<value>jek3</value>
</list>
</property>
</bean>
<property name="sutdents">
<list>
<value>jek1</value>
<value>jek2</value>
<value>jek3</value>
</list>
</property>
</bean>
2.Set 的注入
<bean id="" class="">
<property name="sutdents">
<set>
<value>jek1</value>
<value>jek2</value>
<value>jek3</value>
</set>
</property>
</bean>
<property name="sutdents">
<set>
<value>jek1</value>
<value>jek2</value>
<value>jek3</value>
</set>
</property>
</bean>
3.Map 的注入
<bean id="" class="">
<property name="sutdents">
<map>
<entry key="gf">
<value>jek1</value>
</entry>
<entry key="gd">
<value>jek2</value>
</entry>
</map>
</property>
</bean>
<property name="sutdents">
<map>
<entry key="gf">
<value>jek1</value>
</entry>
<entry key="gd">
<value>jek2</value>
</entry>
</map>
</property>
</bean>
4.properties 的注入
<bean id="" class="">
<property name="sutdents">
<props>
<prop key="gf">jek1</prop>
<prop key="gd">jek2</prop>
</props>
</property>
</bean>
<property name="sutdents">
<props>
<prop key="gf">jek1</prop>
<prop key="gd">jek2</prop>
</props>
</property>
</bean>
十.管理 Bean
Bean 的管理有 3 种方式
public class HelloWorld{
private String msg;
} //Bean 类
private String msg;
} //Bean 类
1.使用 BeanWrapper 管理 Bean //此管理不会使用 Spring 的配置文件,一般不常用