• 不知道是不是还有人来访问,呵呵,很长时间没有更新过了,搬了个家,欢迎大家访问

    http://www.feedhome.com/blog/page/pawa

  • 2003-08-25

    IoC Container

    还真别说,我们还就是决定持久层用hibernate了,这样和gigix的方案一致了。

    关于IoC的使用,我能想到的是在表现层和持久层中间加入服务层,这个服务层全部被封装成为组件,使用container注册、管理、调用,在表现层决不有一行调用持久层的代码,全部放在服务层中,这样表现层可以选择各种不同的框架,我们有很多对Struts很熟悉的人,当时我也是设计了这样的架构,不过没有container的概念,要想实现诸如缓存、灵活控制事务、认证、支持多种表现层、支持多种持久层等就做不到。如果有了container,我想是不是可以把这些功能全部放在container中来进行,开发的服务组件只由商业逻辑,其它一概不管,全部由container完成。

    至于使用那个container,我还在看,有几个选择:

  • PicoContainer 超轻量级,可以随便嵌入到哪里,不过需要自己完成很多代码,来实现我需要的功能,不知道时间是否允许。使用Tape 3 IoC,要用constructor注册,这个也遭到一些非议,这些没有真正使用过,只是感觉,觉得可以省去配置文件,省去设置context,自动找到dependency,不用实现和pico相关的任何接口,方便单元测试(直接new就行啦,不用烦人的mock,呵呵),更多的好处可能仍需观察中。简单是不是一定就是最好的呢?如果够用,我想应该是吧。
  • Spring Framework 次轻量级,这个框架就复杂些了,有从头到脚的DIY方案,提供了一个IoC的容器,有很好的和持久层继承的功能,特别对hibernate有参考实现了。他的文档也有比较详细地介绍,不过他采用的是Type 1 IOC,使用xml来注册管理组件,想一下tapestry就要那么多配置文件,就够烦了,还要再来,还没有工具,真是比较头大。他也比较了和Avalon、Pico的一些不同,我贴在下边,做个参考。
  • WebWork 这个还没有特别仔细看,他把容器部分好像也单独抽取出来形成了xWork框架,似乎完成和pico相似的功能,感觉上可能会考虑的周全些,使用了Type 2 IoC,我在以前的blog也介绍过一下这个东西。

    ----------------
    附:String vs Avalon vs PicoContainer
    Spring Bean Container vs Avalon / Fortress
    Avalon is the oldest IoC container in the field, although still not very prevalent. It is basically just a set of interfaces for components and service managers, with various implementations. Most of the latter are in somewhat unclear states though, the only major ones are Phoenix and Fortress.

    For wiring up, every Avalon component needs to look up cooperating components via the Avalon ServiceManager, passed to it automatically if it implements the Serviceable interface. This is pretty intrusive, as practically every application component with dependencies has to implement that Avalon interface. Furthermore, the lookup mechanism is based on the service interface. If you want to receive a specific instance, you have to use the ServiceSelector with a specific key - another special mechanism.

    A difference in focus shows in that Avalon defines quite a lot of optional interfaces that a component can implement, like Startable, Stoppable, etc. Spring solely offers InitializingBean and DisposableBean as of 1.0 M1, mainly because there has not been demand for explicit start/stop cycles yet. Alternatively, one can also specify an "init-method" and/or "destroy-method" in the bean definition, so that a bean does not even have to implement a Spring-specific interface for such resource handling callbacks.

    Avalon's most important container implementation, Phoenix, targets standalone applications like full servers. Avalon has its advantages there, as it has been designed for start/stop cycles etc. The only stable implementation for embedded use like within a web application is Fortress, which competes with Spring's bean container. Spring focuses on embedded usage as application context, it does not aim to be a foundation for server processes. And of course, Spring's feature set for application development goes far beyond the bean container itself.

    Finally, an example of Avalon's programming model: If you'd like to create the above generic application context with Avalon, you'd have to subclass BasicDataSource and make it implement Configurable (for the parameters) and Stoppable (for the close call), or wrap it in a respective service adapter. Furthermore, "exampleDataAccessObject" would have to implement Serviceable to look up the DataSource, and use the ServiceSelector mechanism to choose one by some key if there were more than one.


    Spring Bean Container vs PicoContainer
    Another lightweight container getting attention recently is the PicoContainer. Its original incentive is to offer a more lightweight and less intrusive model than Avalon. It is built around components that specify dependencies via constructor arguments, instead of having to use some ServiceManager. This infrastructure intends to solve the same problems as Spring's application context concept but has some severe drawbacks:

  • There's no notion of a specific component instance, just one implementation class for any given type. What if one would like to use 2 DataSource instances for 2 databases? How to configure the 2 differently? How to pass a specific one of those to a certain component? This is not possible with PicoContainer: It registers exactly one instance per type.
  • Pico-managed classes are only allowed to have one single constructor, with all objects that the class depends on as arguments. This does not allow for convenient reuse of the class.
  • Using existing classes is hard with PicoContainer: You have to subclass and write a single magic constructor there. Spring has the ability to work with any existing JavaBean.
  • Inheritance is painful and error-prone when constructor chaining is required. Spring can use final bean properties to avoid errors. A constructor (or any method) with 10 arguments is a code smell and suggests refactoring into an initializer object. Spring can easily support this, via a bean reference.
  • Unit tests concern one method of a service object. Why require providing all params to a constructor if you're really interested in the DataSource property etc? You only need to set the properties you require in Spring.
  • JavaBeans are an elegant part of core Java: Why not use them? PicoContainer objects will need to follow a unique constructor pattern.
  • JavaBean properties can be defined on interfaces if appropriate, or concealed if not. Why build constructors (an implementation issue) into an OO framework?
  • Constructors are less obvious in IDEs than bean properties. It's trivial to see the properties on any object.
  • In the future, Spring may offer dynamic reconfiguration of contexts, if beans can handle it by updating individual changed properties. With constructors alone this would mean changing the identity of the component.

    PicoContainer's main advantage is that it does not need instance-specific meta data like XML bean definitions, although it does need some kind of component and parameter registration. As this basic design strategy leads to the above mentioned severe limitations, we consider it questionable. Using very simple XML meta data, Spring offers a significantly more flexible and powerful infrastructure that achieves Pico's goals among other things.

    An example: To create the above generic application context with PicoContainer, you'd have to subclass BasicDataSource to give it one single constructor that takes all "necessary" parameters (is password or validationQuery necessary, for example?), and you would just be able to register one such instance for the DataSource interface (what if you'd like to access 2 databases?).

    P.S. on PicoContainer's new bean-style factory [24-07-2003]

    PicoContainer features a bean-style component factory now, as of 1.0 alpha-2, in response to the first version of this article. This can remedy some of the issues that we've mentioned, although PicoContainer still focuses on the constructor-based approach in all of its documentation.

    Note that the first and most important issue still applies: There is no notion of a specific instance for a given type. We consider passing a reference to a specific instance a very important feature for wiring up applications, which necessarily involves some kind of configuration like in an XML file (Spring makes this pluggable). PicoContainer sacrifices this to be able to adhere to its configuration-less "Type 3 IoC" dogma.

    Finally, regarding the argument that constructor-based "Type 3 IoC" cannot miss any dependencies: Why should every component need to receive instances for all possible dependencies and parameters? A bean-description-based approach, aka "Type 2 IoC" but without "enabler" interfaces, allows for optional dependencies without any hassle. We consider such flexibility more important than to avoid missing dependencies at any cost.

  • 2003-08-18

    Type 3 IOC

    今天开始看IoC了,先主要看了PicoContainer的介绍,发现正是以前我想要得。

    用于MVC中的M层,提供服务组件,自己以前也有一个非常简陋的实现,但是基于继承的,感觉不太好用,虽然能减轻一定的编码工作,但是基本上没有什么重用性可言,因为持久层也是用了自己实现的一个简陋模型,需要在外部控制事务,我的这个服务层,基本上也就是作了控制事务的封装,本意是想实现能够组合组件可以任意开启事务,最大程度上服用这些服务组件,虽然能用,好像并没有达到效果。

    这个PicoContainer应该说能够解决问题了,gigix的分析很到位:

    “IOC也是个老词了,用它的另一个名字或许更容易理解——“好莱坞原则”:don't call us, we will call you. 也就是说,每个component是passive的,只有framework是active的,component的initialization和invocation都由framework管。”

    具体讲到PicoContainer,号称是Type 3 IoC,怎么就变成Type3了呢?呵呵,让我的感觉是其实只是每个组件注册时候采用的方式不同,不过其他基本属性应该是一致的。

    下边摘录了一下他们三种的区别:

    Type 1 IoC (the Avalon way) forces components to be decode their own configuration metadata. Too intrusive.

    Type 2 IoC (the XDoclet way) looks cleaner: metadata is separated from code (albeit not from the source). But there's more to composition than property setting.

    Type 3 IoC looks like an attempt to disguise compositional metadata by placing it in the least imaginable place: the component's constructor! Again, there's more to composition than property setting.
  • 终于有别人也来看我的blog了
    只是自己水平有限,对不住大家:〉

    看了最近一期的程序员,才知道WebWork也是Richard Orberg的产品,看了他在freeroller上的blog,似乎很推崇IOC和AOP。他也提到了gigix提到的PicoContainer,这两天准备看看,正好我们要使用Tapestry作为表示层开发了,一定要找一个服务层和持久层的东西来支撑。
  • 2003-07-25

    EclipseUml

    好早就下载了EclipseUml(一个功能强大的免费的不是open source的eclipse插件,可以画出各种Uml图,还能反向工程),不过一直没有用起来,昨天终于要用了……结果有点失望啊。功能确实很强,画出来的图也很好看,不过只有一点,也是致命的一点,速度太慢,不是一般的慢阿,如果开启了任何一个Uml图,整个eclipse就会狂慢,每次保存什么文件都要很长时间这段时间CPU占用率100%什么事情也做不了,太痛苦了。

    我想可能是因为EclipseUml类图需要实时跟java文件同步导致了这样的结果,找了半天也没有发现那里有设置不让他自动同步。

    看来软件如果光是功能好界面好还不行,最关键还要可用阿,想想编辑一个文件时间都花费在保存上,这还怎么用啊。想想自己以前做东西只管能实现什么都不管,真是汗颜……

    要做可用的软件
  • AOP != Interception
    AOP isn't interception as in AOP is interception and more. This is my AOP manifesto, the least common denominator of all AOP systems (well, according to me at least):
  • Interception As in "not being equal to AOP", also known as advice in the more academic AOP-world. It's basically the act of adding further processing to certain locations in a system. The locations are called points or join-points and an advice(interceptor) is typically applied to a set of points or a pointcut. I'm not convinced much more than method-interception is needed, but that's what is required at the very least.
  • Introduction Do you remember your first lessons in object-oriented programming? The whole point was to modularize by encapsulating state and behaviour. So if interception is behaviour, introduction is state. Introduction should also make it possible to add further behaviour to an object, but in contrast to interception this behaviour is not interleaved with the existing code.
  • Inspection This is somewhat a new area for the new wave of open-source AOP, but in some ways runtime attributes and method-names-patterns are in this are. While I don't believe field-interception is strictly necessary I do believe it's necessary to access information on what a methods does, what fields it modifies, what methods it calls, who calls this method, and so on... For example a object-relational framework could load fields from the database before the execution of a method that uses these fields. A transaction could be started if a method is called from the user-interface and if that method is modifying some external resource or persistent fields, directly or indirectly.
  • Modularization Not only must it be possible to intercept, introduce and inspect, one must also be able to encapsulate it all in aspects. An aspect modularize the entire crosscutting concern (such as persistence, undo, transactions, locking, caching and so on) into one single module (possibly consisting of several sub-aspects, by delegation, inheritance or composition). This could be a Java-class or even... *yuck* XML.

    If you ain't got all of this, you ain't worthy being called 'AOP'. :-)

    原文联接 http://freeroller.net/page/tirsen/20030618
  • 只因为这个类别有点特殊哦
    现在JAVA开放源码社区,对这个东西很是热
    不过仍然属于比较前沿的领域
    我要给与更多的关注和学习