一 IOC (inversion of control)
控制反转是为了降低程序的耦合性。首先我们看下程序之间的关系。
程序之间的关系:
依赖:
B对象的方法需要用到A对象
e.g. exampleTest(A,a);
继承:
B对象是一个A对象
e.g. A is a B
聚合:
B对象中有一个A对象
e.g. A has a B
耦合性:
当对象与对象之间存在聚合和依赖关系时,彼此之间必定存在耦合性,虽然面向接口编程可以让我们只关注接口的实现。但是如果在程序中写死:
UserDao userDao = new UserDaoImp();
我们若要更换实现类,则需要修改源程序。工厂模式在接口和实现类中充当媒介
UserDao userDao = factroy.createUserDaoImp();
尽管这里是通用语句,更换实现类对此处不影响,但是在工厂类中
return new UserDaoImp();
这里依旧需要修改源代码。所以我们采用IOC方式,用配置文件,反射的方式去维护程序,避免了修改源码,实现最大程度上的解耦。
<bean id="userDao" class="xxx.UserDaoImp"></bean>
将类的更换通过反射 Class.forName("xxx.UserDaoImp")来实现,这样就只需要修改配置文件,而不需要修改源代码了。
Spring工厂类
BeanFactroy
老版本,在调用getBean()的时候才生成类的实例
ApplicationContext
新版本,在加载配置文件时全部生成类的实例
两个实现类:
ClassXmlPathApplicationContext 加载在类路径下的配置文件
FileSystemXmlApplicationContext 加载系统(盘符)路径下的配置文件
Bean的相关内容
<bean>标签
name 属性不唯一,可以使用特殊字符
id 属性唯一,不可以使用特殊字符,其他和name没有差别
bean的作用范围
singleton 单例
prototype 多例
request 在Web应用中,Spring将生成的类实例存入到request中
session 在Web应用中,Spring将生成的类实例存入到session中
globalsession 在Web应用中,如果不是porlet环境,则和session没有区别
bean的实例化方式
空参构造(默认)
<bean id="userDaoId" class="xxx.UserDaoImp"></bean>
静态工厂
<bean id="userDaoId" class="xxx.StaticFactroy" factroy-method="createUserDaoImp"></bean>
实例工厂
<bean id="factroyId" class="xxx.Factroy"></bean>
<bean id="userDaoId" factroy-bean="factroyId" factroy-method="createUserDaoImp"></bean>
二 DI (dependency injection)
因为是在配置文件中创建类对象,所以对象的各属性同样需要在配置文件中写入,这就需要依赖注入DI。
构造方法的属性注入
public Animal(String name, String type,Food food) {
....
}
<constructor-arg name="name" value="小猪“></constructor-arg>
<constructor-arg name="type" value="pig"></constructor-arg>
<constructor-arg name="food" ref="food"></constructor-arg>
set方法的属性注入
注意:此方法必须类里有空参构造方法
此方法必须有对应的setXxx的方法
<property id="name" value="小猪”></property>
<property id="type" value="pig”></property>
<property id="food" ref="food”></property>
p名称空间的属性注入(Spring2.5以后)
引入p名称空间
xmlns:p="http://www.springframework.org/schema/p"
用法
普通属性 p:属性名="值"
对象属性:p:属性名-ref="值"
<bean id="animal" class="xxx.Animal" p:name="小猪“ p:type="pig" p:food-ref="food"></bean>
SpEL(Spring Expression Language)
用法 #{ 。。。} 代替 ”。。。“
。。。可以放各种基础属性,int,double,String等
可以放实例化后对象名(id), 对象名.属性 , 对象名.方法
集合类型属性注入
数组型 e.g. String[] strings
<property name="strings">
<list>
<value>字符1</value>
...
</list>
</property>
List e.g. List list
<property name="list">
<list>
<value>元素1</value>
...
</list>
</property>
Set e.g. Set set
<property name="set">
<set>
<value>元素1</value>
...
</set>
</property>
Map e.g. Map map
<property name="map">
<map>
<entry key=" " value=" "></entry>
...
</map>
</property>
三 Spring的分模块开发配置
1. 在加载配置文件的时候加载多个
ApplicationContext ac = new ClassXmlPathApplicationContext("xxx.xml", "xxx02.xml",...);
2. 在一个配置文件中引入多个配置文件
<import resource="xxx.xml"></import>
努力生活,自得其乐 —— 2019.03.22