Spring源代码解析(一):IOC容器【转载计文柯书籍】 (十一)

2014-11-24 08:46:51 · 作者: · 浏览: 7
,我们可以把它看成是一个抽象工厂,对它的调用返回的是工厂生产的产品。所有的 Factory bean都实现特殊的org.springframework.beans.factory.FactoryBean接口,当使用容器中factory bean的时候,该容器不会返回factory bean本身,而是返回其生成的对象。Spring包括了大部分的通用资源和服务访问抽象的Factory bean的实现,其中包括:
对JNDI查询的处理,对代理对象的处理,对事务性代理的处理,对RMI代理的处理等,这些我们都可以看成是具体的工厂,看成是SPRING为我们建立好的工厂。也就是说Spring通过使用抽象工厂模式为我们准备了一系列工厂来生产一些特定的对象,免除我们手工重复的工作,我们要使用时只需要在IOC容器里配置好就能很方便的使用了。
现在我们来看看在Spring的事件机制,Spring中有3个标准事件,ContextRefreshEvent, ContextCloseEvent,RequestHandledEvent他们通过ApplicationEvent接口,同样的如果需要自定义时间也只需要实现ApplicationEvent接口,参照ContextCloseEvent的实现可以定制自己的事件实现:


[java]
public class ContextClosedEvent extends ApplicationEvent {

public ContextClosedEvent(ApplicationContext source) {
super(source);
}

public ApplicationContext getApplicationContext() {
return (ApplicationContext) getSource();
}
}

public class ContextClosedEvent extends ApplicationEvent {

public ContextClosedEvent(ApplicationContext source) {
super(source);
}

public ApplicationContext getApplicationContext() {
return (ApplicationContext) getSource();
}
}
可以通过显现ApplicationEventPublishAware接口,将事件发布器耦合到ApplicationContext这样可以使用 ApplicationContext框架来传递和消费消息,然后在ApplicationContext中配置好bean就可以了,在消费消息的过程中,接受者通过实现ApplicationListener接收消息。
比如可以直接使用Spring的ScheduleTimerTask和TimerFactoryBean作为定时器定时产生消息,具体可以参见《Spring框架高级编程》。
TimerFactoryBean是一个工厂bean,对其中的ScheduleTimerTask进行处理后输出,参考ScheduleTimerTask的实现发现它最后调用的是jre的TimerTask:


[java]
public void setRunnable(Runnable timerTask) {
this.timerTask = new DelegatingTimerTask(timerTask);
}

public void setRunnable(Runnable timerTask) {
this.timerTask = new DelegatingTimerTask(timerTask);
}
在书中给出了一个定时发送消息的例子,当然可以可以通过定时器作其他的动作,有两种方法:
1.定义MethodInvokingTimerTaskFactoryBean定义要执行的特定bean的特定方法,对需要做什么进行封装定义;
2.定义TimerTask类,通过extends TimerTask来得到,同时对需要做什么进行自定义
然后需要定义具体的定时器参数,通过配置ScheduledTimerTask中的参数和timerTask来完成,以下是它需要定义的具体属性,timerTask是在前面已经定义好的bean


[java]
private TimerTask timerTask;

private long delay = 0;

private long period = 0;

private boolean fixedRate = false;

private TimerTask timerTask;

private long delay = 0;

private long period = 0;

private boolean fixedRate = false;
最后,需要在ApplicationContext中注册,需要把ScheduledTimerTask配置到FactoryBean - TimerFactoryBean,这样就由IOC容器来管理定时器了。参照
TimerFactoryBean的属性,可以定制一组定时器。

[java]
public class TimerFactoryBean implements FactoryBean, InitializingBean, DisposableBean {

protected final Log logger = LogFactory.getLog(getClass());

private ScheduledTimerTask[] scheduledTimerTasks;

private boolean daemon = false;

private Timer timer;

...........
}

public class TimerFactoryBean implements FactoryBean, InitializingBean, DisposableBean {

protected final Log logger = LogFactory.getLog(getClass());

private ScheduledTimerTask[] scheduledTimerTasks;

private boolean daemon = false;

private Timer timer;

...........
}
如果要发送时间我们只需要在定义好的ScheduledTimerTasks中publish定义好的事件就可以了。具体可以参考书中例子的实现,这里只是结合FactoryBean的原理做一些解释。如果结合事件和定时器机制,我们可以很方便的实现heartbeat(看门狗),书中给出了这个例子,这个例子实际上结合了Spring事件和定时机制的使用两个方面的知识 - 当然了还有IOC容器的知识(任何Spring应用我想都逃不掉IOC的魔爪:)www.2cto.com


最后来总结下吧,对于普通ioc容器启动到被客户端使用的步骤大致如下:
定义-