1.原则: Don't call us,we will call you
2.原来构建对象,对象内如果有其他依赖对象,需要一个个构建后传入,现在直接先注入好,构建原对象的时候
它会直接向Ioc service Provider 去要
3.注入对象的方式有
A. 构造方法方式注入
B.通过setter 方式注入
C.实现提供的接口来注入
4.Ioc service provider 有两种功能
A. 业务对象构建管理
B. 业务对象间依赖绑定
5.Ioc service provider 简化代码来构建对象,但是这些依赖条件Ioc service provider
如何知道?
A.直接编码方式知道
比如
IoContainer container=...
container.register(FXNewProvider.class,new FXNewsProvider());
B.配置文件方式
<bean id="newsProvider" ...>
....
</bean>
C.通过注解来注入
6.Spring Ioc 容器
Ioc service provider 是其中的一部分
Ioc 容器spring提供两种类型
A.BeanFactory :基础类型Ioc 容器 默认为延时初始化策略,启动快需要资源有限
B.ApplicationContext:BeanFactory 基础上构建,属于高级容器,提供事件发布,国际化等
高级功能,需要资源相对多,启动相对也就慢。
7.bean 的生命周期
A.singleton: 在spring Ioc 容器中只存在一个实例,他的生命周期从容器启动并因为第一次被
请求而初始化后,将一直存活到容器退出。这里的singleton 和Gof中提出的Singleton 有点区别
bean的singleton 表示在同一个容器中存在一个实例;而Gof中的Singleton表示同一个classloader中
只存在一个实例。
B.prototype:代理
容器在接收到请求后,为之生成一个新对象实例给请求方,然后就不再有新对象的引用。
C.request,session,global session
只适用web 应用,不像上面的那么通用。通常与XmlWebApplicationContext一起用
request:每一个请求生成一个新的requestProcessor 对象,和http request的生命周期一样
session:和http session 生命周期一个
global session:只应用在基于portlet 的web应用程序才有意义。映射到portlet的global
范围的session
D.自定义scope类型
实现org.springframework.beans.factory.config.Scope接口
public infterface Scope{
...
}
其中get和remove 方法必须实现,参考例子
http://jroller.com/eu/entry/more_fun_with_spring_scopes
有了Scope的实现类后,需要把Scope注册到容器中,才能提供相应的bean定义
通过ConfigurableBeanFactory的 registerScope中进行注册。BeanFactory
通常实现ConfigurableBeanFactory接口。
如果是ApplicationContext,你还可以通过配置文件来实现,ApplicationContext
会自动识别并加载.
E.面向接口编程指以接口为导向,在类中引用接口而不是具体接口的实现类,这样就减少和
特定实现类的耦合,比如传统写法
public class Foo{
private BarInterface barInstance;
public Foo()
{
barInstance = new BarInterfaceImp();
//BarInterfaceImp其实是BarInterface 接口的实现类
}
}
上面的写法耦合很大,如果该类是由我们设计并开发的,那么还好说,我们可以通过依赖注入,
让容器帮助我们解除接口和实现类之间的耦合性,但是,有时,我们需要依赖第三方库,需要实例化
并通过第三方库中的相关类,这时,接口和实现类的耦合性需要其他方式来避免。
比如工程方法模式。提供一个工厂类来实例化具体的接口实现类,这样主体对象只需要依赖工厂类,具体使用的实现类有变革的话,只要变更工厂类。
上面的Foo可以改为:
public class Foo{
private BarInterface barInterface;
public Foo()
{
//barInterface = BarInterfaceFactory.getInstance();
或者
//barInterface =new BarInterfaceFactory().getInstance();
}
}
静态工厂方法:
public class StaticBarInterfaceFactory
{
public static BarInterface getInstance()
{
return new BarInterfaceImpl();
}
}
spring 提供配置来支持静态工厂方法
<bean id="bar" class="...StaticBarInterfaceFactory" factory-method="getInstance">
//如果factory-method 有参数可以,进入下面参数
<constructor-arg>
<ref bean="foobar">
</constructor-arg>
</bean>
非静态工厂方法:
public class NoStaticBarInterfaceFactory
{
public BarInterface getInstance()
{
return new BarInterfaceImpl();
}
}
spring配置如下:
<bean id="barFactory" class="...NoStaticBarInterfaceFactory" />
<bean id="bar" factory-bean="barFactory" factory-method="getInstance" />
FactoryBean:spring 提供的生产对象的工厂bean
只需要实现org.springframework.beans.factory.FactoryBean 接口
public interface FactoryBean{
//获取实例
Object getObject() throws Exception;
//获取实现相对于的类型
Class getObjectType();
//表明获取的实例在容器中是否是singleton形式
boolean isSingleton();
}
然后在spring 进行bean定义
<bean id="objectId" class="...FactoryBean"/>需要注意的是,这里的objectId不是
FactoryBean类型,而是上面实现接口的具体getObjectType的类型。
F.方法注入和方法替换。
方法替换实现org.springframework.beans.facotry.support.MethodReplacer
并在bean中定义
<replaced-method name="getAndPersistNews" replacer="providerReplacer"/>
<bean id="providerReplacer" class="...FXNewsReplacer">
其实方法替换就是对方法的拦截。
G.ApplicationContext特性
Resource:spring 定义统一的资源
ResourceLoader:有了资源,需要有加载工具。
ResourcePatternResolver:是ResourceLoader的扩展,resourceLoader每次只能根据
资源返回单个Resource实例,而ResourcePatternResolver可以一次返回多个Resource