Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: Meta-data hell

  1. #1

    Default Meta-data hell

    I'm writing a new application (as it happens it's a Swing application) using Spring and I'm using a beans.xml to wire it up (including GUI elements like the main frame and menu bar etc: no I'm not using the Spring thick client project).

    The up side is that a lot of the setup code I normally have to write has gone, which is great. But. My beans.xml file is getting big and it contains a lot of knowledge about how the application is built.

    This isn't my first Spring application: I've built a web app using it before and in a J2EE environment you kind of become immune to large meta-data files so I didn't really notice Spring's being a problem.

    However in J2SE applications lots of meta-data isn't the norm' so I'm noticing the size of the beans.xml file much more than I did before.

    So my question is: how is the beans.xml file not an example of meta-data hell and a centralised controller of everything, which are two things I thought Spring was supposed to help with? Am I missing something?

    Edward

  2. #2
    Join Date
    Aug 2004
    Location
    Toulouse, France
    Posts
    148

    Default

    If you centralize eveything in a single beans.xml, it can become very large, indeed.
    However, there are a couple of tricks which can be used to limit this.

    First, applicationContext are hierarchical. Even if it isn't exactly the desired effect, if you feel like there's a default behaviour and then specialized applicationContext, you can hierarchize and thus split files.
    On another side, you can use several files which describes different parts of your application (UI, DAO, core, remoting e.g. ...) and have then "merged" when building the applicationContext. Have a look at http://www.springframework.org/docs/....String[]) for instance, you're giving several paths and there are logically merged. This is an interesting technique.
    You can also split files and have then "merged" implicitely with the help of the recent addition of the include feature in the beans.xml. You can then have a single entry point and <include ...> all the others. This is similar to the previous approach.
    Hope it helps

    Olivier

  3. #3
    Join Date
    Aug 2004
    Location
    Melbourne, FL
    Posts
    2,794

    Default

    Edward,

    What are you wiring up? If you are wiring up extremely fine grained Swing components, you're really using Spring XML for something it was not intended to be used for.

    I would recommend at least taking a look at how the Spring Rich project recommends externalizing GUI configuration (via the Petclinic sample), as it strikes a nice balance--one leveraging Spring's configuration mechanism for the declarative definition of application command bars and views (somewhat coarse grained), while delegating to java-coded component factories encapsulating creation of complex controls assembled from lower-level Swing widgets. Even if you don't use it now, you can take away a considerable amount of lessons learned on building Swing apps atop Spring's IoC container.

    Regards,
    Keith
    Keith Donald
    Core Spring Development Team

  4. #4

    Default

    Quote Originally Posted by kdonald
    What are you wiring up?
    Hi Keith

    on the UI side I'm wiring up strategys to actions to menu items to menus to menu bars to a JFrame. So not especially fine grained.

    Edward

  5. #5

    Default

    Hi Oliver

    Yes I've thought about splitting my beans.xml but: that doesn't actually make the effective beans.xml any smaller and it does add another element of complexity. In any case I can't see that it adds any more than commenting blocks of xml in one big beans.xml. If the imported elements could be made modular, with an interface of "exported" elements that could be used (and an XML editor could prompt for as with any modern Java editor) then that would be useful: but I don't believe that's the case.

    Edward

  6. #6
    Join Date
    Aug 2004
    Location
    Melbourne, FL
    Posts
    2,794

    Default

    It's worth noting Spring rich has several fairly innovative ways of substantially reducing the amount of GUI configuration information the developer must specify, through use of BeanPostProcessors and other abstractions such as shared TargetableActionCommands (part of the Spring rich command/action framework.)

    Just one example: command (action) implementations are typically defined via bean definitions managed by a per-application-window scoped bean factory, but injected their visual configuration properties automatically via a strategy object acting as a BeanPostProcessor. This "Configurer" strategy supports internationalization and the ability to assign different visual representations of a command's actionable controls (buttons, menu items, etc) for different presentation contexts...

    You'll likely find that direct instantiation of Swing widgets in a spring application context doesn't scale very well. For example, what about when you need support for multiple application windows? Or the case where the same command should be invokable by different controls on different command bars? Spring rich already has support for that, in a fashion I would call a best practice, via its higher-level abstractions that build on the low-level Swing widgets. Petclinic illustrates all this nicely, and several users have mentioned leveraging it as a reference app to be a small investment in time (saving you, at the very least, time having to worry about managing application windows/views and command bars yourself.)
    Keith Donald
    Core Spring Development Team

  7. #7
    Join Date
    Aug 2004
    Location
    Melbourne, FL
    Posts
    2,794

    Default

    Edward,

    Attached is the "commands-context.xml" definition from PetClinic, representing a per-application-window scoped bean factory definition for command bars (menu bars, tool bars, etc.)

    Note the use of FactoryBeans to produce the underlying command groups, which themselves are factories for the underlying grouping GUI controls (menus, toolbars, popup menus, button bars, etc). Likewise, note the definition of various ActionCommands, like the "AboutCommand" or "HelpContentsCommand", which themselves are factories for the underlying actionable controls (buttons, menu items, toggle buttons.) Thirdly, note the definition of the "newOwnerCommand", which is a TargetableActionCommand whose implementation is delegated to an ActionCommandExecutor strategy, notably the "NewOwnerWizard", encapsulating the creation of a WizardDialog to step the user through creating a new Pet owner. This allows for easy parameterization of command execution without the need to subclass. Fourthly, note there is no manual definition of command visual properties: e.g icons, labels, mnemonics, accelerators, etc. This is all handled by the Configurer BeanPostProcessor strategy I mentioned, pulling from a .properties file for injecting potentially locale-specific visual command configuration.

    One last point: the "sharedCommands" property of the ApplicationWindowCommandManager defines commands whose implementation may be retargeted to local executors when the "active view" within the application window changes (for example, allowing the shared "Properties" or "Delete" commands to execute differently based on context.)

    Regards,

    Keith

    Code:
    <beans>
    	
       <bean id="windowCommandManager" class="org.springframework.richclient.application.support.ApplicationWindowCommandManager">
    		<property name="sharedCommandIds">
    			<list>
    				<value>saveAsCommand</value>
    				<value>propertiesCommand</value>
    				<value>undoCommand</value>
    				<value>redoCommand</value>
    				<value>cutCommand</value>
    				<value>copyCommand</value>
    				<value>pasteCommand</value>
    				<value>selectAllCommand</value>
    				<value>deleteCommand</value>
    			</list>
    		</property>
    	</bean>
    	
    	<bean id="menuBar" 
    		class="org.springframework.richclient.command.CommandGroupFactoryBean">
    		<property name="members">
    			<list>
    				<ref bean="fileMenu"/>
    				<ref bean="editMenu"/>
    				<ref bean="windowMenu"/>
    				<ref bean="helpMenu"/>
    			</list>
    		</property>
    	</bean>
    	
    	<bean id="toolBar" 
    		class="org.springframework.richclient.command.CommandGroupFactoryBean">
    		<property name="members">
    			<list>
    				<ref bean="newMenu"/>
    				<value>saveAsCommand</value>
    			</list>
    		</property>
    	</bean>
    	
    	<bean id="fileMenu" 
    		class="org.springframework.richclient.command.CommandGroupFactoryBean">
    		<property name="members">
    			<list>
    				<ref bean="newMenu"/>
    				<value>separator</value>
    				<ref bean="loginCommand"/>
    				<ref bean="logoutCommand"/>
    				<value>separator</value>
    				<value>saveAsCommand</value>
    				<value>separator</value>
    				<value>propertiesCommand</value>
    				<value>separator</value>
    				<bean class="org.springframework.richclient.command.support.ExitCommand"/>
    			</list>
    		</property>
    	</bean>
    	
    	<bean id="newMenu" 
    		class="org.springframework.richclient.command.CommandGroupFactoryBean">
    		<property name="members">
    			<list>
    				<ref bean="newOwnerCommand"/>
    			</list>
    		</property>
    	</bean>
    	
    	<bean id="newOwnerCommand" 
    		class="org.springframework.richclient.command.TargetableActionCommand">
    		<property name="commandExecutor">
    			<ref bean="newOwnerWizard"/>
    		</property>
    	</bean>
    	
    	<bean id="editMenu" 
    		class="org.springframework.richclient.command.CommandGroupFactoryBean">
    		<property name="members">
    			<list>
    				<value>undoCommand</value>
    				<value>redoCommand</value>
    				<value>separator</value>
    				<value>cutCommand</value>
    				<value>copyCommand</value>
    				<value>pasteCommand</value>
    				<value>separator</value>
    				<value>selectAllCommand</value>
    				<value>deleteCommand</value>
    			</list>
    		</property>
    	</bean>
    	
    	<bean id="windowMenu" 
    		class="org.springframework.richclient.command.CommandGroupFactoryBean">
    		<property name="members">
    			<list>
    				<bean class="org.springframework.richclient.command.support.NewWindowCommand"/>
    				<value>separator</value>
    				<bean class="org.springframework.richclient.command.support.ShowViewMenu"/>
    			</list>
    		</property>
    	</bean>
    	
    	<bean id="helpMenu" 
    		class="org.springframework.richclient.command.CommandGroupFactoryBean">
    		<property name="members">
    			<list>
    				<ref bean="helpContentsCommand"/>
    				<value>separator</value>
    				<ref bean="aboutCommand"/>
    			</list>
    		</property>
    	</bean>
    	
    	<bean id="helpContentsCommand" 
    		class="org.springframework.richclient.command.support.HelpContentsCommand"/>
    		
    	<bean id="aboutCommand" 
    		class="org.springframework.richclient.command.support.AboutCommand">
    		<property name="aboutTextPath">
    			<value>org/springframework/richclient/samples/petclinic/about.txt</value>
    		</property>
    	</bean>
    	
    	<bean id="loginCommand" 
    		class="org.springframework.richclient.security.LoginCommand">
    		<property name="authenticationManager">
    			<ref bean="authenticationManager"/>
    		</property>
    	</bean>
    	
    	<bean id="logoutCommand" 
    		class="org.springframework.richclient.security.LogoutCommand"/>
    
    </beans>
    Keith Donald
    Core Spring Development Team

  8. #8

    Default

    Quote Originally Posted by kdonald
    Attached is the "commands-context.xml" definition from PetClinic,
    Hi Keith

    As a I read your message and worked my way down the commands-context.xml I first thought: "hmm neat". And then I thought "Oh my God look at the size of this thing and all it's doing is setting up some menus" and finally I thought: "actually all of the cleverness appears to be in the classes and doesn't really depend on Spring core at all: couldn't they be put to better use programmatically building a Swing application?"

    Edward

  9. #9

    Default

    Hi Keith

    Quote Originally Posted by kdonald
    You'll likely find that direct instantiation of Swing widgets in a spring application context doesn't scale very well.
    Yes I'd agree with that: I'd pretty much come to the conclusion that Spring is useful for configuring Actions (in menus and toolbars) but that was about it.

    I certainly wouldn't even bother trying to use to build any major element of the GUI. (When I say "Spring" here I'm using it as short hand for "a Spring configuration.xml file").

    Quote Originally Posted by kdonald
    Or the case where the same command should be invokable by different controls on different command bars?
    Standard Actions can be used to configure toolbars, menus and buttons.

    Edward

  10. #10
    Join Date
    Aug 2004
    Location
    Melbourne, FL
    Posts
    2,794

    Default

    You can use the API's programatically, with no problem. Just like any Spring solution, the APIs are very well developed and are designed for direct use. In this case, the command API, which bulds on Swing's action framework, is quite more capable and powerful than plain-old Swing actions or action listeners.

    So in effect, Spring XML is just one way of wielding our API--through metadata that "tells the Spring bean factory" how to instantiate, configure, and connect our application objects.

    I must admit I don't think that XML here is very verbose. (and to be quite honest I'm one to run very far away very fast at the site of LoC-hell.) It's pretty straightforward, actually, and a lot is being done for you (configuration, internationalization, delegation to pluggable component factories for component creation, lazy loading, etc)

    With externalized configuration it's also very easy and quick to change a command bar item--no recompilation neccessary. Opportunties to simplify metadata LoC with lightweighting scripting technologies like Groovy and Beanshell are on the Spring 1.2 horizon.

    One last point: you can't quite see it here, but this example is connecting the middle tier service layer (or service proxy layer, if the client/server version) to the UI layer: Spring is extremely good at service wiring/binding via this configuration mechanism, in this case connecting the "Clinic" service facade to the "newOwnerWizard" control factory singleton for wiring the UI layer up with middle tier services (decoupling UI from any middle-tier lookup or configuration glue code.) You don't see this here because this is the command bar definition for the application--which is instantiated on a per window basis, and are "child contexts" of a root-level rich-client application context (where global application-scoped singleton service definitions are declared.)
    Keith Donald
    Core Spring Development Team

Similar Threads

  1. Replies: 3
    Last Post: Oct 31st, 2005, 02:29 AM
  2. Replies: 2
    Last Post: Oct 18th, 2005, 10:08 AM
  3. Multiple Data Sources + Hibernate + Spring
    By joeserel in forum Data
    Replies: 2
    Last Post: May 18th, 2005, 09:22 AM
  4. injecting complex configuration data
    By fox9 in forum Container
    Replies: 2
    Last Post: Feb 25th, 2005, 07:23 AM
  5. Data Secutiry - Filtering Data
    By porcelli in forum Security
    Replies: 3
    Last Post: Dec 30th, 2004, 12:01 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •