论坛首页 Java企业应用论坛

Yan Container beta 1 发布

浏览 36121 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2005-04-07  
ajoo 写道
引用
为啥string没有被set,它不会抱怨

找时间我跑跑你的test case。
不过哪里有个string?你不就是一个bar, 一个list吗?

给那个Foo对象加一个string属性以及setter.

跑前面的测试用例时候, 只报错java.util.List不能被resolve, 按照道理String也应该报出来呀? 莫非你设计的时候, 只报第一个不能被resolve的setter?
0 请登录后投票
   发表时间:2005-04-07  
是的。遇到第一个错误就直接异常退出了。
pico也是如此啊。难道spring是所有错误一股脑都报告出来?
component创建可是可能有副作用的啊。难道遇到错误了,还接下来创建其它component比如open connection?
0 请登录后投票
   发表时间:2005-04-07  
spring里的autowire
<!--
	Optional attribute controlling whether to "autowire" bean properties.
	This is an automagical process in which bean references don't need to be coded
	explicitly in the XML bean definition file, but Spring works out dependencies.

	There are 5 modes:

	1. "no"
	The traditional Spring default. No automagical wiring. Bean references
	must be defined in the XML file via the <ref> element. We recommend this
	in most cases as it makes documentation more explicit.

	2. "byName"
	Autowiring by property name. If a bean of class Cat exposes a dog property,
	Spring will try to set this to the value of the bean "dog" in the current factory.
        If there is no matching bean by name, nothing special happens - use
	dependency-check="objects" to raise an error in that case.

	3. "byType"
	Autowiring if there is exactly one bean of the property type in the bean factory.
	If there is more than one, a fatal error is raised, and you can't use byType
	autowiring for that bean. If there is none, nothing special happens - use
	dependency-check="objects" to raise an error in that case.

	4. "constructor"
	Analogous to "byType" for constructor arguments. If there isn't exactly one bean
	of the constructor argument type in the bean factory, a fatal error is raised.

	5. "autodetect"
	Chooses "constructor" or "byType" through introspection of the bean class.
	If a default constructor is found, "byType" gets applied.

	The latter two are similar to PicoContainer and make bean factories simple to
	configure for small namespaces, but doesn't work as well as standard Spring
	behaviour for bigger applications.

	Note that explicit dependencies, i.e. "property" and "constructor-arg" elements,
	always override autowiring. Autowire behaviour can be combined with dependency
	checking, which will be performed after all autowiring has been completed.
-->
<!ATTLIST bean autowire (no | byName | byType | constructor | autodetect | default); "default">

<!--
	Optional attribute controlling whether to check whether all this
	beans dependencies, expressed in its properties, are satisfied.
	Default is no dependency checking.

	"simple" type dependency checking includes primitives and String
	"object" includes collaborators (other beans in the factory);
	"all" includes both types of dependency checking
-->
<!ATTLIST bean dependency-check (none | objects | simple | all | default); "default">
0 请登录后投票
   发表时间:2005-04-07  
多谢,多谢。

byName是个有趣的功能。我考虑下个版本会加入对它的支持。

optional property我也考虑增加。目前想象中的语法应该这样:


Components.bean(Foo.class);
.optional("list");;


既然spring是找不到组件是nothing-happen,而二义性则报错,我也可以照猫画虎。
0 请登录后投票
   发表时间:2005-04-07  
问题解决。

增加了optionalProperty和ignoreProperty两个combinator。

你的问题可以写成这样:
bean(Foo.class);.optionalProperty("list");;


当然,你还是要显式说明你的property是optional的。容器缺省认为所有property都是mandatory的。
只在property对象解析失败或者是它的某个零件解析失败的时候起作用。
对其它错误,如cyclic dependency, ambiguity, 动态component中出现的错误等等仍然直接抛出异常。

这个变化还没有upload到sourceforge上去。想要现在看的可以从cvs上下载。
0 请登录后投票
   发表时间:2005-04-07  
对了。nihongye兄,你觉得spring的byName有实际价值吗?
如果没什么意义我就懒得加它了。
0 请登录后投票
   发表时间:2005-04-07  
呼呼。睡觉前show一下。
刚刚写了关于byname的代码。

自觉的很爽的是,不需要改动任何库代码,直接就可以在客户程序里面支持这个功能。而且,不像pico,稍微复杂一点的要求就让你自己实现ComponentAdapter(基本上等于告诉你:这个功能啊?好办。去home depot买锤子和水泥,你可以自己盖这个房子啊!我们支持DIY,灵活吧?)

    public static PropertyDescriptor[] getBeanProperties(Class c);
    throws java.beans.IntrospectionException{
      return Introspector.getBeanInfo(c);.getPropertyDescriptors();;
    }
    public static Component bean_byname(final Component cc, final Class type);
    throws IntrospectionException{
      final PropertyDescriptor[] props = getBeanProperties(type);;
      Component r = cc;
      for(int i=0; i<props.length; i++);{
        final PropertyDescriptor prop = props[i];
        if(prop.getWriteMethod(); == null); continue;
        final String name = prop.getName();;
        r = Components.bean(r, new String[]{name});
          .optionalProperty(name);
          .withProperty(name, Components.useKey(name););
          
          ;
      }
      return r;
    }
    public static Component bean_byname(final Component cc);
    throws IntrospectionException{
      final Class type = cc.getType();;
      if(cc.getType();==null);{
        return jfun.yan.monad.Monad.bind(cc, new jfun.yan.monad.Binder();{
          public Creator bind(Object obj);
          throws Exception{
            if(obj==null); return Components.value(null);;
            else return bean_byname(Components.value(obj);, obj.getClass(););;
          }
        });;
      }
      else{
        return bean_byname(cc, type);;
      }
    }

getBeanProperties是一个工具函数,负责对某一个类得到它的properties。它只依赖标准jdk库。

第一个bean_byname函数是在已知一个Component的类型的条件下,对每个property都调用bean(r, new String[name]),这个函数仅仅负责设置那个叫name的property。
然后,用optionalProperty来说明这个property是optioinal的。
然后,用withProperty(name, Components.useKey(name))来达到byName的功能。

如此一个bean套一个bean,最终达到处理所有property的目标。


第二个bean_byname函数是一般性的处理任何组件。如果一个组件的类型未知(比如它是一个useKey之类的),那么,它用Monad.bind()函数来在动态取得这个组件的类型,然后再调用第一个bean_byname函数。



下面是test case

    public static final class Civilian{
      private String dog;
      private String cat;
      private String wife = "do not need";
      public String getCat(); {
        return cat;
      }
      public void setCat(String cat); {
        this.cat = cat;
      }
      public String getDog(); {
        return dog;
      }
      public void setDog(String dog); {
        this.dog = dog;
      }
      public String getWife(); {
        return wife;
      }
      public void setWife(String wife); {
        this.wife = wife;
      }
    }

    public void testBeanByName();
    throws Exception{
      final YanContainer yan = createYanContainer();;
      yan.registerValue("dog", "Bach");;
      yan.registerValue("cat", "Chopin");;
      yan.registerComponent("civilian", bean_byname(Components.ctor(Civilian.class);););;
      yan.registerComponent("civilian2", bean_byname(Components.useKey("civilian");););;      yan.verify();;
      Civilian civ = (Civilian);yan.getInstance("civilian");;
      assertEquals("Bach", civ.getDog(););;
      assertEquals("Chopin", civ.getCat(););;
      assertEquals("do not need", civ.getWife(););;
      civ = (Civilian);yan.getInstance("civilian2");;
      assertEquals("Bach", civ.getDog(););;
      assertEquals("Chopin", civ.getCat(););;
      assertEquals("do not need", civ.getWife(););;
    }


这个例子相当程度上表达了yan在灵活性上的优势。基本上你很少很少需要自己实现Component。只需要拿来系统预定义的一些component,然后用组合子把它们组合起来,就可以达到很多我现在也想不到的功能。


这也基本上说服我,不必要增加直接对byName的支持。
其实,用上面的方法,我们也可以增加byDisplayName(用descriptor.getDisplayName()而不是getName()),byClassNamePlusPropertyName(用class.getName()+'.'+descriptor.getName())等等功能。
这些都可以在外围库或者客户代码中做到,又何必内建在库里面呢?

库所要做的只是提供尽量多的简单得原子功能和组合能力,复杂的component就不必要亲历亲为了。

哈哈。
0 请登录后投票
   发表时间:2005-04-07  
自我陶醉的家伙! 大家有空要狠狠打击他!    

我胡思乱想了一下,组装组件似乎可以分为这么两种:
1)全局组装+局部组装结合
2)智能式自动组装
3)支持运行时线程安全组装

我个人认为以上4种方式将是将来IOC容器必须具备的功能之一。  哈哈

 

举个例子说,还是以偶比较熟悉的Spring来说吧
<bean id="beanA" class="com.javaeye.BeanA">
		<property name="beanC"><ref bean="beanC"/></property>
		<property name="mappingResources">
			<list>
<value>1,2,3,4,5,6,7</value>
			</list>
		</property>
		<property name="name">ajoo hao!</property>
<property name="beanB"><ref bean="beanB"/></property>
	</bean>
<bean id="beanB" class="com.javaeye.BeanB">
		<property name="beanC"><ref bean="beanC"/></property>
		<property name="mappingResources">
			<list>
<value>1,2,3,4,5,6,7</value>
			</list>
		</property>
		<property name="name">ajoo hao hao hao!</property>
	</bean>




对于以上配置文件,如果我选用AJOO兄的Yan作为我的IOC容器,那么我会读取这个配置文件,并以Yan为容器核心进行装配,此时,类似的代码如下:
final DefaultContainer cc = new DefaultContainer();
  //读入组件beanA配置文件信息
引用
  <bean id="beanA" class="com.javaeye.BeanA">
<property name="beanC"><ref bean="beanC"/></property>
<property name="list">
<list>
<value>1,2,3,4,5,6,7</value>
</list>
</property>
<property name="name">ajoo hao!</property>
<property name="beanB"><ref bean="beanB"/></property>
</bean>

Component compA=Components.BeanWithClassName(“com.javaeye.BeanA");; //读取配置文件第一行得出的代码 ,告诉容器可以调用new Bean(); 生成实例,然后以Bean setter方式进行  组装

compA=compA.globalProperty("beanC");; // 读取到<ref bean="beanC"/> 时知道ref代表全局组装,告诉容器这个组件的属性beanC需要在全局寻找零件进行组装 。
compA=compA.localProperty(“list");; //因为没有ref引用,所以是局部组装
List list= ... //读取配置文件中1,2,3,4,5,6,7生成list
cc.registerValueForLocalWireUpComponent("beanA","list", list);; //这一行代码告诉容器,对于组件beanA的组装,其中其属性list的组装应该引用前面生成的list
cc.registerComponent("beanA",compA);; //最后一行完成对这个组件的注册
 


读取到beanB和BeanC时类似,值得注意的是,当最后读取配置文件完毕,应用中需要获取BeanA的实例时,Yan容器必须能够对BeanA,BeanB,BeanC之间的依赖性进行解析和有顺序的组装。

以上的分析就是全局+局部 和 智能式组装。
0 请登录后投票
   发表时间:2005-04-07  
打击呀,打击呀,拿出上次对付jf的劲头来。:D


所以与你们争辩,就如同和小儿吵架,几乎没有对等讨论性,我真是非常孤独,偌大中国,在Java技术领域,如同红卫兵小将占据话筒。

本来我还想谦虚一些,现在我更可以理直气壮地宣称:
Yan Container是民族软件的骄傲,我在2005五一前夕勇敢地写下这段话,当你们“长大”后,也会会为之骄傲。

Yan Container是目前中国水平最高的框架之一。它几十个类不是普通Java程序员能在短时间内看懂的。
0 请登录后投票
   发表时间:2005-04-08  
最后想说一下线程安全的组件组装。
假设组件是一个由状态的组件时,那么它可能需要在并发情况下进行组件组装,值得注意的是,这个组件的状态对象零件仅仅对这个组件的组装有意义,而对其他组件是不可见的。 那么此时就需要考虑并发线程安全的组件组装。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics