Uploaded image for project: 'Spring Framework'
  1. Spring Framework
  2. SPR-230

Please improve BeanFactory support for containers & collections

    Details

    • Type: Improvement
    • Status: Resolved
    • Priority: Major
    • Resolution: Won't Fix
    • Affects Version/s: 1.0.2
    • Fix Version/s: None
    • Component/s: Core
    • Labels:
      None
    • Last commented by a User:
      true

      Description

      Objects that contain other objects (common examples include Swing Containers and the Collections classes) frequently cannot have their initial state specified through setting javabeans properties alone.

      This is a request for the spring core to include extensions to the syntax of the applicationContext.xml to allow such objects to be setup completely from XML. Some reasonably conveinient syntax is needed that allows methods like "add()" to be invoked on the bean at construction time. Ideally, I think the syntax should allow any arbritrary methods to be called on a bean during preparation.

      There is a clear precendent to be found in the design of the java.beans.XMLEncoder/Decoder classes, designed to support long term bean perisstence. Consider the extract below generated by XML-serializing a List:

      <?xml version="1.0" encoding="UTF-8" ?>
      <java version="1.4.2_03" class="java.beans.XMLDecoder">
      <object class="java.util.ArrayList">
      <void method="add">
      <string>item</string>
      </void>
      </object>
      </java>

      Evidently, it was recognized as an important feature as its present from the first release of the peristence mechanism.

      Consider what is not readily doable from XML without this feature:

      • Cannot create any Swing component heirarchies.
      • Cannot initialize custom collections (ie anything not a vanilla set/map/list impl), unless it provides a copy-constructor.
      • Cannot init arbritrary state on objects which do not observe the get/setXXX convention (and legacy code is littered with them).

        Issue Links

          Activity

          Hide
          tawek Tomasz Wysocki added a comment -

          As for annotation stuff I don't use it much and I've been using spring since its 1.0 times with xml configuration only. Juergen had proposed to support this feature using @Autowired annotations (see comments above). Probably it could have been made that way but from my point of view the xml syntax is still the king and it has to be supported approach.

          At least simple <util:invoke> to simplify the (mis)use of MethodInvocationFactoryBean could be introduced if there is too much resistance to introduce new things in "beans" namespace.

          Or maybe we should look at simple invocation facility from different perspective which escapes "programming in xml" argument. If we are doing COP with spring then when calling a method what we are really doing is registering a new plugin (or listener or collaborator in general). Look at SPR-2533 and other similar issues.

          Currently spring supports only specifying collaborators at target site like below:

          <bean name="composite">
          <property name="component" ref="componentA"/>
          </bean>

          <bean name="componentA"/>

          and it supports only one collaborator per property specified at target - "composite" site. What if we "IoC"?

          <bean name="composite"/>

          <plugin target="composite" role="component">
          <bean name="componentA"/>
          </plugin>

          Not very different but opens a lot of other possibilities like:

          1. you don't have to connect plugins at composite site, rather at component (plugin) site - this would typically require postprocessors.
          2. you can register many "plugins" if target "composite" supports it.
          3. you could specify what methods not only to register but also what methods to use to unregister the plugin!
          4. you could even use interface name instead as role name - so that you don't specify the target name - this is similar to @Autowire by type

          Also you can then specify the name of register/unregister methods at "composite" or "plugin" site. I would argue to define such "plug-points" at "composite" site like this:

          <bean name="composite">
          <plug-point
          role="component" // this is an association name - like property name -
          [register-method="add

          {role}"] // optional method name to register plugin, by default it can follow "add{role}

          " or "register

          {role}" pattern
          [unregister-method="remove{role}

          "] // optional method name with reverse effect to register
          [cardinality="0..n"] // how may collaborators are supported
          />
          </bean>

          Lots of new ground to cover, but we really start talking plugins! But probably too much to make it into 3.0.

          Show
          tawek Tomasz Wysocki added a comment - As for annotation stuff I don't use it much and I've been using spring since its 1.0 times with xml configuration only. Juergen had proposed to support this feature using @Autowired annotations (see comments above). Probably it could have been made that way but from my point of view the xml syntax is still the king and it has to be supported approach. At least simple <util:invoke> to simplify the (mis)use of MethodInvocationFactoryBean could be introduced if there is too much resistance to introduce new things in "beans" namespace. Or maybe we should look at simple invocation facility from different perspective which escapes "programming in xml" argument. If we are doing COP with spring then when calling a method what we are really doing is registering a new plugin (or listener or collaborator in general). Look at SPR-2533 and other similar issues. Currently spring supports only specifying collaborators at target site like below: <bean name="composite"> <property name="component" ref="componentA"/> </bean> <bean name="componentA"/> and it supports only one collaborator per property specified at target - "composite" site. What if we "IoC"? <bean name="composite"/> <plugin target="composite" role="component"> <bean name="componentA"/> </plugin> Not very different but opens a lot of other possibilities like: 1. you don't have to connect plugins at composite site, rather at component (plugin) site - this would typically require postprocessors. 2. you can register many "plugins" if target "composite" supports it. 3. you could specify what methods not only to register but also what methods to use to unregister the plugin! 4. you could even use interface name instead as role name - so that you don't specify the target name - this is similar to @Autowire by type Also you can then specify the name of register/unregister methods at "composite" or "plugin" site. I would argue to define such "plug-points" at "composite" site like this: <bean name="composite"> <plug-point role="component" // this is an association name - like property name - [register-method="add {role}"] // optional method name to register plugin, by default it can follow "add{role} " or "register {role}" pattern [unregister-method="remove{role} "] // optional method name with reverse effect to register [cardinality="0..n"] // how may collaborators are supported /> </bean> Lots of new ground to cover, but we really start talking plugins! But probably too much to make it into 3.0.
          Hide
          iterator Dirk Scheffler added a comment -

          Probably you misunderstood the annotations. They are not a replacement for the XML and they are not comparable to @Autowired. But let us forget the annotations because they seem not to belong here. So I am fully with you to discuss the invocation xml stuff.

          I think we should not forget that this feature is not only a search for the best design but mainly a helper for legacy objects that are NOT designed with Spring in mind. So I would still see the best way by having the invocation element as you typed some posts before. A higher level design could be a parallel approach with more efforts to avoid programing in xml.

          I find the suggestion to place it in the util namespace (<util:invoke>) very good. So developers dedicated to a clear cut regarding programming in xml and with a pure spring friendly program design will not find it as a core feature of the beans namespace. My opinion is that you should go that way:

          <bean id="someBean" class="SomeClass">
            <util:invoke method="addEntry">
              <value>foo</value>
              <value>bar</value>
            </util:invoke>
            <!-- alternatively in cases where neccessary because of overloading -->
            <util:invoke method="addEntry(java.lang.String,java.lang.String)">
              <value>foo</value>
              <value>bar</value>
            </util:invoke>
          </bean>

          Show
          iterator Dirk Scheffler added a comment - Probably you misunderstood the annotations. They are not a replacement for the XML and they are not comparable to @Autowired. But let us forget the annotations because they seem not to belong here. So I am fully with you to discuss the invocation xml stuff. I think we should not forget that this feature is not only a search for the best design but mainly a helper for legacy objects that are NOT designed with Spring in mind. So I would still see the best way by having the invocation element as you typed some posts before. A higher level design could be a parallel approach with more efforts to avoid programing in xml. I find the suggestion to place it in the util namespace (<util:invoke>) very good. So developers dedicated to a clear cut regarding programming in xml and with a pure spring friendly program design will not find it as a core feature of the beans namespace. My opinion is that you should go that way: < bean id = "someBean" class = "SomeClass" > < util :invoke method = "addEntry" > < value >foo</ value > < value >bar</ value > </ util :invoke> <!-- alternatively in cases where neccessary because of overloading --> < util :invoke method = "addEntry(java.lang.String,java.lang.String)" > < value >foo</ value > < value >bar</ value > </ util :invoke> </ bean >
          Hide
          iterator Dirk Scheffler added a comment -

          Regarding the higher level approach. Where I am basically with you is the point that linking should be reversable. But this is should also be possible for normal properties. I think a real good IoC container would manage not only DI (Dependency Injection) but also DS (Dependency Seperation) which would be running after the lifecycle of some bean is beeing finished. I have often tought about this. My dream is a language design for a programming language that has IoC in mind. Java is not really made for that. I am sure that there will come a time where this will be the conclusion of all the IoC experiences: Create a new language that supports separation of concerns (implementation vs. wiring) and this language should have a more direct syntax than XML for wiring. This would be very funny to discuss about such a language. Probably one should start some thread about that idea.

          Show
          iterator Dirk Scheffler added a comment - Regarding the higher level approach. Where I am basically with you is the point that linking should be reversable. But this is should also be possible for normal properties. I think a real good IoC container would manage not only DI (Dependency Injection) but also DS (Dependency Seperation) which would be running after the lifecycle of some bean is beeing finished. I have often tought about this. My dream is a language design for a programming language that has IoC in mind. Java is not really made for that. I am sure that there will come a time where this will be the conclusion of all the IoC experiences: Create a new language that supports separation of concerns (implementation vs. wiring) and this language should have a more direct syntax than XML for wiring. This would be very funny to discuss about such a language. Probably one should start some thread about that idea.
          Hide
          jerryshea Jerry Shea added a comment -

          my 2 cents: I just want to able to do event wiring in Spring java just like Spring.NET

          Show
          jerryshea Jerry Shea added a comment - my 2 cents: I just want to able to do event wiring in Spring java just like Spring.NET
          Hide
          cbeams Chris Beams added a comment -

          Most if not all of the use cases represented here can be addressed with Spring 3.0 and 3.1 using the code-based @Configuration class approach.

          Please take a look at this style if you haven't already – we think that it represents a flexible and natural way to configure any Java object, especially when injection needs don't closely fit the JavaBeans model.

          You can get started by looking at the Javadoc for @Configuration, which is rather extensive and complete with cross-references to the other types you'll need to know about. http://static.springsource.org/spring/docs/3.1.0.M2/javadoc-api/org/springframework/context/annotation/Configuration.html

          Show
          cbeams Chris Beams added a comment - Most if not all of the use cases represented here can be addressed with Spring 3.0 and 3.1 using the code-based @Configuration class approach. Please take a look at this style if you haven't already – we think that it represents a flexible and natural way to configure any Java object, especially when injection needs don't closely fit the JavaBeans model. You can get started by looking at the Javadoc for @Configuration , which is rather extensive and complete with cross-references to the other types you'll need to know about. http://static.springsource.org/spring/docs/3.1.0.M2/javadoc-api/org/springframework/context/annotation/Configuration.html

            People

            • Assignee:
              cbeams Chris Beams
              Reporter:
              ben_hutchison Ben Hutchison
              Last updater:
              Trevor Marshall
            • Votes:
              32 Vote for this issue
              Watchers:
              28 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Days since last comment:
                5 years, 51 weeks, 3 days ago