作者:江南白衣 原文地址:

http://www.blogjava.net/calvin/archive/2005/08/30/11099.html

http://www.blogjava.net/calvin/archive/2005/08/26/11243.html

DreamHead在《思考微内核》十分激赏 Spring的微内核与扩展机制:
“Spring的微内核在哪里呢?便是DI容器。而通过FactoryBean,我们可以定制自己的组件组装过程,对一个普通的JavaBean做手脚,像Spring AOP中常用的ProxyFactoryBean做的那样。如此,我们就不必把所有功能都做到Spring的DI容器中去,而是以一个FactoryBean来对DI容器的功能进行扩展。除了Spring自身之外,现在已经有一些项目开始利用这个特性扩展Spring,比如,Acegi Security和Spring Modules。”

这确是框架容器界应该贯彻的范式,微内核提供最少的功能,而由扩展接口去增强框架的能力。下面看看Spring怎么设计,明白之后就可以开始为Spring捐献精力了:)

1、微内核的功能
1.1 DI(依赖注入)与Singleton管理
      利用POJO setter的DI机制,估计每位同学随手都能写一个简单版本,不多说了。
      Singleton管理说白了就是先到一个map中按id找找看有没有已存在的实例。

1.2 BeanName与BeanFactory注入
      除了DI注入的属性,微内核还有什么能卖给POJO呢?就是Bean在xml 定义里的id和BeanFactory自己了。
      卖的机制是让POJO 实现 BeanNameAware和BeanFactoryAware接口。BeanFactory用 if(pojo instance of BeanFactoryAware)判断到POJO需要注入BeanFactory,就调用setBeanFactory(this)将自己注入。

这种框架中基于接口的注入和调用机制在Java下挺标准的,Spring的功能多是基于这种模式提供。遗憾就是Java不支持多重继承,作为替代的接口里不能提供默认的实现,导致每一个Pojo都要很无聊的实现一遍setBeanFactory()。

1.3 DI后的初始化函数调用
      比如属性A,B注入之后,需要同时根据A和B来对A,B进行加工或者装配一个内部属性C,这样就需要在所有属性注入后再跑一个init()函数。
      Spring提供两种方式,一种是和上面的原理一样,实现InitializingBean接口的afterPropertiesSet()函数供Spring调用。
      一种是在xml定义文件里面自行定义init函数名。
      懒得每次在xml文件里定义的就采用第1种方式,不想与spring耦合的pojo就采用第2种方式。本来就是为了扩展Spring而存在的FactoryBean多采用第一种。

所谓微内核,就是仅提供以上三种功能的DI容器。
   但作为轻量级容器,还需要以下两种方式,向容器内的POJO 附加各种服务。

2.FactoryBean扩展机制
Spring的AOP、ORM、事务管理、JMX、Quartz、Remoting、Freemarker、Velocity,都靠FacotryBean的扩展,FacotryBean几乎遍布地上:

<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"/>

<bean id="baseDAOService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"/>

只不过当年对这类factoryBean比较麻木不仁,不问原理的照搬照用了。

不过这原理说出来也好简单,所有FactoryBean 实现FactoryBean接口的getObject()函数。Spring容器getBean(id)时见到bean的定义是普通class时,就会构造该class的实例来获得bean,而如果发现是FacotryBean接口的实例时,就通过调用它的getObject()函数来获得bean,仅此而以.......可见,很重要的思想,可以用很简单的设计来实现。

考察一个典型的FactoryBean:
    一般会有两个变量,三个接口:
    一个setter函数注入需要改装的pojo,一个内部变量保持装配后的对象returnOjbect。
    implements三个接口 :FactoryBean,InitializingBean和BeanFactoryAware 。
    各接口的意义之前都讲过了。factoryBean会在afterPropertiesSet()里把pojo改装成returnObject,需要用到beanfactory进行天马行空的动作时就靠BeanFactoryAware注入。最后在getObject()里把returnObject返回。

Rod说:IoC principles, combined with the factory bean, afford a powerful means to abstract the act of obtaining or accessing services and resources

3. Bean Post-Processor扩展机制
     如果说FactoryBean 是一种Factory、Wrapper式的扩展,Bean Post-Processor就是另一种AOP、visitor式的机制,所以也多用于spring的AOP架构。
      Post-Processor的原理就是BeanFactory在前文里的调用afterPropertiesSet()/init-method前后,调用在工厂里注册了的post-processor的postProcessBeforeInitialization()和postProcessAfterInitialization()。
      那怎么注册登记呢?又分请不请礼仪公司两类。如果是ApplicationContext,你把继承BeanPostProcessor 的bean往xml里一搁就行了,application context自会打理。如果是BeanFacotry,就要显式的注册,代码大概像:

XmlBeanFactory factory = new XmlBeanFactory("C:/beans.xml"); 
BeanPostLogger logger = new BeanPostLogger(); 
factory.addBeanPostProcessor(logger);

Rod说:"Post-processors add the ability to customize bean and container behavior in a flexible, externalized fashion. "
对比Factory Bean那段,可见两种机制在他心目中的不同作用。

扩展Spring(2) ---Spring对各种数据访问框架的集成机制

     何为数据框架集成。
   数据访问框架原本好好的,Spring都干了什么呢?
   一是用template类封装了数据框架那些资源获取和异常事务处理的废话代码,而且按照自己的意见给出一些增强函数。
   二是将其纳入了Spring的声明式事务管理中。

对比Spring对Hibernate、JDBC的集成,还有Spring ModulesO/R Broker的集成,发现Spring的DAO框架主要有六个类:
    1.Template 
      著名的Template类,用callback机制封装了除业务代码外的所有必要但废话的代码,重新封装了数据框架的API,并再附送一些增强版。

2.TransactionManager 
      实现PlatformTransactionManager接口,数据访问框架就能与Spring的事务机制(TransactionTemplate或AOP声明式事务)结合。

    重要的类仅以上两个,以下的类都只有少量标准代码,完全可以忽略。
    
3.DAOSupport
       实际DAO类的基类,负责保持template变量。如果你觉得它破坏了你的类层次结构,完全可以不用。
    4.Accessor
     template类的基类,defining common properties like DataSource and exception translator,也没大用。
    5.Operations
     template所实现的接口,定义template支持的数据访问函数和增强函数,template有多个实现时才有用。
    6.Exception Translate的相关类和函数
     异常翻译,Spring DAO很重视的一个功能。

Template类的代码
   因为Hibernate本身很复杂,所以HibernateTemplate也不适合畏高晕车的人士如我观看。JDBC简单很多,但JDBCTemplate又忙着增强JDBC的功能,多出好多代码。所以我选O/R broker的集成代码来看,代码一共才280行。
注:如果不熟O/R broker,可以简单的认为broker=connection, executable = statement ,其余一切同Jdbc。

1.1主干函数 Execute(BrokerCallback action)
      step1. 获得Connection-- connecton = datasource.getConn();
      step2. 准备Statement -- statement = new Statement(connection);
      step3. 执行Action的回调函数doInBroker(Statement)。这个doInBroker()方法由客户定义,会拿着传入的statement,执行种种操作。

 try
{
  action.doInBroker(statement );
}
catch()
{
   //翻译异常
}

1.2 template的API函数
         虽然理论上大家可以直接使用execute(),在匿名内部类里调用数据访问框架的任何API。但java的匿名内部类不比闭包,代码难看无比,所以除了Robbin还没见到其他兄弟提倡直接用execute方法的。
        因此,template也对数据框架的API进行了wrap,封装了用execute(StatementCallback action)来执行这些API的函数,如下段就是wrap 了O/R Broker的execute(String statementID.....)方法:

public int execute(final String statementID, final String[] paramNames, final Object[] values) throws DataAccessException {
    return executeWithIntResult(new BrokerCallback() {
      public Object doInBroker(Executable executable) throws BrokerException {
        applyNamedParamsToExecutable(executable, paramNames, values);
        return new Integer(executable.execute(statementID));
      }
    });
  }

另外还提供一些增强型、便利型的API(如selectOne() ,selectMany()),在参数、返回值上极尽变化。

TransactionManager的代码
   比较复杂,一下说不清。但JDBC的DatasourceTransactionManager和Hibernate的HibernateTransactionManager的代码都很相近,说明这个TransactionManager其实也比较固定埋头狂抄就是了。

有兴趣的同学,可以响应某大老号召,实现ofbiz与spring的集成:)

Spring 的微内核与FactoryBean扩展机制--转载的更多相关文章

  1. Spring Cloud 中自定义外部化扩展机制原理及实战

    Spring Cloud针对Environment的属性源功能做了增强, 在spring-cloud-contenxt这个包中,提供了PropertySourceLocator接口,用来实现属性文件加 ...

  2. 聊聊spring的那些扩展机制

    1.背景 慎入:本文将会有大量代码出入. 在看一些框架源码的时候,可以看见他们很多都会和Spring去做结合.举个例子dubbo的配置: 很多人其实配置了也就配置了,没有去过多的思考:为什么这么配置s ...

  3. Spring Schema扩展机制

    1:概述 Spring2.0开始,Spring提供XML Schema可扩展机制,用户可以自定义XML Schema文件,并自定义 XML Bean解析器,集成到Spring IOC容器中. 2:步骤 ...

  4. 缘起 Dubbo ,讲讲 Spring XML Schema 扩展机制

    背景 在 Dubbo 中,可以使用 XML 配置相关信息,也可以用来引入服务或者导出服务.配置完成,启动工程,Spring 会读取配置文件,生成注入 相关 Bean.那 Dubbo 如何实现自定义 X ...

  5. 聊聊 Spring 的 XML Schema 扩展机制的使用方式

    前言 在当前Java生态,Spring算的上是最核心的框架,所有的开发组件想要得到大范围更便捷的使用,都要和Spring进行整合,比如我们熟知的Mybatis.Dubbo等,以及内部封装的各类组件包括 ...

  6. Spring.factories扩展机制

    和Java SPI的扩展机制类似,Spring Boot采用了spring.factories的扩展机制,在很多spring的starter 包中都可以找到,通过在 META-INF/spring.f ...

  7. Spring中自定义Schema扩展机制

    一.前言 Spring 为基于 XML 构建的应用提供了一种扩展机制,用于定义和配置 Bean. 它允许使用者编写自定义的 XML bean 解析器,并将解析器本身以及最终定义的 Bean 集成到 S ...

  8. Spring中BeanFactory与FactoryBean的区别

    在Spring中有BeanFactory和FactoryBean这2个接口,从名字来看很相似,比较容易搞混. 一.BeanFactory BeanFactory是一个接口,它是Spring中工厂的顶层 ...

  9. 聊聊Dubbo - Dubbo可扩展机制实战

    1. Dubbo的扩展机制 在Dubbo的官网上,Dubbo描述自己是一个高性能的RPC框架.今天我想聊聊Dubbo的另一个很棒的特性, 就是它的可扩展性. 如同罗马不是一天建成的,任何系统都一定是从 ...

随机推荐

  1. 【C++对象模型】构造函数语意学之一 默认构造函数

    默认构造函数,如果程序员没有为类定义构造函数,那么编译器会在[需要的时候]为类合成一个构造函数,而[需要的时候]分为程序员需要的时候和编译器需要的时候,程序员需要的时候应该由程序员来做工作,编译器需要 ...

  2. android测试本地服务调试流程

    我今天调试的整个过程 1,安卓发现连不上本地的tomcat 2,使用浏览器直接尝试,发现可以连上 3,怀疑是安卓APP和浏览器访问有差异,后上网搜索不到APP,只有浏览器尝试       再不就是改I ...

  3. bzoj 2002 [Hnoi2010]Bounce 弹飞绵羊(LCT)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2002 [题意] 给定n个数的序列,i可以跳到i+k[i],需要能够修改k并可以查询跳出 ...

  4. Ruby多字节字符的设计

    Perl.Python的多字节字符处理方式是UCS(Universal Code Set),Ruby的多字节字符处理方式是CSI(Code Set Independent).UCS的做法是,不管你读取 ...

  5. 50道经典的JAVA编程题(汇总)

    这是一次不可思议的编程历程.从2013年的最后一天开始做这份题,中间连续好几天的考试,包括java考试(今天考试的JAVA编程题),直到今天完成了.挺有成就感的...废话不多说了,来电实质性的吧. 全 ...

  6. MongoVUE 如何导出数据

    1.MongoVUE导出数据 正常连接如数据后,打开对应数据库的collections,然后点击右上角的“Refresh”的下拉小三角,打开export 根据个人喜好,或业务需求,选择导出的格式 最后 ...

  7. http协议中的Content-Type

    今天对http协议中的Content-Type有所理解了 它的主要功给我的感觉,还是在前台(客户端)给服务器传输数据时,描述这个数据的格式. 比如,我只传一个表单数据,但这个表单中只有文本,没有其它的 ...

  8. WebBrowser实现编辑网页

    //1.显示网页 procedure TForm2.FormCreate(Sender: TObject); begin Panel1.Align := alTop; CheckBox1.Anchor ...

  9. 问题-某个程序改了ICO图标后编译后还是显示老图标?

    问题现象:某个程序改了ICO图标后编译后还是显示老图标? 问题原原:可能是因为系统的缓存问题. 问题处理:把程序的EXE放在别的路径下打开就可以了. 问题相关人员:QQ253120114(朋友)  Q ...

  10. red5下nginx安装配置

    http://zfl110.iteye.com/blog/1155149 原址:http://lqw.iteye.com/blog/652763 安装Nginx 1.首先安装pcre-8.02.tar ...