Brian's first post just shows the very basic setup (how to specify the classes that Swiz manages and how to load them into your application).
If you're using ColdSpring today in CFML and you're interested in learning Flex, Brian's series might be very useful to you.
If you're tired of the boilerplate code that Cairngorm makes you write (or generate), Swiz might be just what you're looking for and Brian's series will be good reading for you too.
We use Swiz at Broadchoice, in our Workspace for Salesforce desktop application (built with Flex and AIR) and we all love working with the framework!
Commercial use will be just $99/user per year with educational licenses at $49/user per year. Registered non-profit organizations can get free licenses.
If you're also a Salesforce user, you'll love the integration between groups in Workspace and your company's Salesforce account, allowing you to see open opportunities directly in the Workspace and create collaborative spaces based on opportunities so that you can work with your non-Salesforce peers on closing deals!
Working with Brian Kotek, Joe Rinehart and Ray Camden on this application has been a wonderful experience. We've all learned a lot from each other as we've learned a lot about Flex, AIR, Groovy, BlazeDS, Spring, Hibernate and integration with CFML via Model-Glue 3 (Gesture) and ColdSpring!
Also, for Workspace users on-the-go, there is an iPhone-compatible web application (with plans for full Blackberry support by year end).
Next up was Mark Drew, covering ColdSpring. A great introduction to basic ColdSpring then on to AOP and remote proxies. I acted as a "bean factory" that helped Mark get ready for work: he asked me for his jacket and I ensured that it contained his iPod and his cigarettes, which in turn meant adding his headphones and his lighter. His examples were amongst the best I've seen for introducing ColdSpring concepts.
Peter Bell is up now, giving his Rapid OO talk - similar to what he did at Scotch. Some good, pragmatic advice about when to bend (or even break) the "rules" of OO that can make you more productive.
After lunch, it's Mike Brunt (Clustering), me (Subversion branches), Kurt Wiersma (development environment) and Gert Franz (Railo 3.1). More on that later.
There is a brand new quick start guide fully updated for the 1.2 release courtesy of Broadchoice's own Brian Kotek. It covers everything from the most basic usage of ColdSpring up to AOP and remote proxies and includes parent beans and factory beans, both of which I use a lot.
- Adobe Keynote - Adam Lehman and Claude Englebert
- ColdSpring - Mark Drew
- RAD Object-Oriented CFML Development - Peter Bell
- High Availability: Clustering ColdFusion Applications - Mike Brunt
- Subversion: Better Living Through Branches - Sean Corfield
- Setting up a Solid Local Development Environment - Kurt Wiersma
- Railo 3.1: The Open Source Story - Gert Franz
We'll be back in September with Seth Duffey and image manipulation.
We use Transfer for all our persistent business objects and almost all of our business objects have a decorator defined (for validation or some additional business logic). We also use Brian's TDOBeanInjectorObserver to automatically inject services into our business objects - just add a setter for a service and the bean injector takes care of the rest.
Here's the bean injector definition in our ColdSpring file:
<constructor-arg name="transfer"><ref bean="transfer" /></constructor-arg>
<constructor-arg name="suffixList"><value>service,datasource</value></constructor-arg>
<constructor-arg name="debugMode"><value>true</value></constructor-arg>
</bean>
So how do we add the on-demand encryption to our business object's data?
The platform is powered by ColdFusion 8.0.1, running Model-Glue 2 (BER), ColdSpring 1.2 BER and Transfer 1.0 BER and runs on a cluster of 64-bit Linux servers with synchronization of the Transfer cache managed through a set of ActiveMQ JMS server instances. The database is MySQL.
We're continuing to work on a stream of minor releases as well as planning our next major release with a lot of new features.
I'll be pulling together some presentations and articles about how we're using the frameworks together (because I think we're doing some interesting and unusual things, behind the scenes). I'll some a few snippets of code at Scotch in both of my presentations (and again at CFUNITED). I'm talking to the CFDevcon organizers about appropriate topics and they suggested a framework-related session so that might be the first unveiling of some of our ColdSpring / Transfer tricks and tips. I expect Ray will also be blogging about some aspects of our application architecture in due course.
Feel free to sign up for a free Broadchoice account and see what we've been up to! Our support site (also powered by the Broadchoice Web Platform, as is our public website - we like to eat our own dog food!) has several ways for you to provide feedback to us!
Here's what I said in response:
We've worked hard to make cf.Objective() 2008 a "must see" event. We have a number of firsts this year that we're very proud of:
- The public release of Open BlueDragon on May 3rd!
- The public unveiling - and Alpha - of Model-Glue 3: Gesture!
- The public unveiling of Mate, the new Flex framework from AsFusion!
- The first conference to feature the latest rising star in the frameworks world: ColdBox - with an introductory session and a two hour, hands-on advanced workshop!
- The first public information about Swiz, the new Flex framework from Chris Scott of ColdSpring fame!
- Speaking of Chris Scott, we're the first conference to feature a two-hour, hands-on workshop for ColdSpring!
- We're also the first conference to feature a two-hour, hands-on workshop on agile development for ColdFusion developers by the leading light in automated process & testing, John Paul Ashenfelter!
If you're a Mach-II user - or thinking of using Mach-II - you might also be interested in the pre-conference classes.
I know Brian Ghidinelli also ran into this issue and had started to write his own as well. I expect he'll switch to Brian Kotek's version now.
So what does it do? Well, as you build complex domain objects by writing decorators for Transfer objects, you find you need access to services that you are managing with ColdSpring. Transfer provides an event model so you can add a listener (observer) for the afterNew event and use that to inject dependencies into your domain objects. It's a fairly manual process. What Brian's CFC does is completely automate the process. You declare the injector in your ColdSpring file and pass in Transfer to its constructor. When ColdSpring initializes the injector, the injector registers itself as an observer for that event and then it automatically injects any matching services, based on setters in the decorator. Very slick!
This is also great news for folks who feel constrained to only use official releases. The last official release of ColdSpring (1.0) was so long ago that lots of great features are only available in the BER: aliases, includes, abstract beans etc. This has been particularly troublesome for such folks trying to use Model-Glue with Transfer (or Reactor) since that has relied on aliases for quite a while. A new official release of ColdSpring (1.2) is just around the corner!
The exception from Reactor - about the database mismatch - is swallowed by ColdSpring and reported as a bean initialization exception. If that in turn is caught and dealt with by the application's initialization code, you no longer have any indication of what the problem might be.
Fortunately, we have a great tool at our disposal to dig into these buried exceptions: the ColdFusion 8 debugger!
I fired up the debugger in Eclipse and enabled break on CFML exceptions and write exceptions to the Eclipse log. As expected with ColdSpring and its exception-happy nature, I hit a few false starts but then I hit the Reactor exceptions. There are a couple of harmless exceptions as it tests for some optional plugin points but then you get the real exception, showing up in the Eclipse log. Very convenient!
Model-Glue has come on in leaps and bounds - the rearchitecture based on ColdSpring, the scaffolding infrastructure, the integrated support for Reactor and Transfer for "generic database messages". It's very impressive. And now we're got the beginnings of a Flex version, which is very promising.
Now that I'm consulting and have a number of clients, I'm encountering Mach-II quite a bit and looking at the 1.5 release. I've mentioned in the past that I think 1.5 looked quite impressive (when Peter Farrell gave the "what's new?" talk at cf.Objective(), for example). Recently, I've been making recommendations for frameworks for clients and finding myself recommending Mach-II for some clients, mostly due to the new features in 1.5. For some of the sites my clients are trying to build, the modules, includes and subroutines really do allow you to build much larger, much more modular sites than earlier versions of Mach-II.
The extended property semantics in Mach-II 1.5 are also very nice, allowing you to specify structured configuration data - including full-on CFCs - as well as allowing property values to be dynamically substituted into parameter values throughout the configuration.
I still don't really like the direct invocation model (with <notify>) compared to Model-Glue's broadcast / listener mechanism, but the other features are pretty compelling.
One thing I have seen mentioned, but cannot find, is Peter Farrell's new ColdSpringProperty CFC, to replace the old ColdSpringPlugin. Anyone know where to get a copy?
I haven't actually watched the preso but I have said publicly that I don't use the proxy generator in ColdSpring - because I don't think you can automatically generate an appropriate remote proxy for a model in the general case.
Next up I covered the Fusebox 5.5 release which is currently in limited Alpha with a public Beta planned in July (as soon as we can get enough documentation together on the new features). I also announced publicly that providing a migration path for Fusebox 3 was on the roadmap (for Fusebox 5.7 probably).
Matt Woodward (and Peter Farrell) presented Mach II 1.5 which is in Beta right now, and the new website. He also talked about plans for their 2.0 release (but didn't go into specifics).
Next up was Chris Scott, who said that an official 1.2 release would appear within a few weeks and then they would be working toward a 1.5 release. This will be the last release of ColdSpring that will run on CFMX 7 - ColdSpring 2.0 will require CF8 because they want to take advantage of cfinterface and onMissingMethod() to make ColdSpring faster (and simplify the core files).
Last up was Doug Hughes who assured us that Reactor would hit an official 1.0 release as soon as the documentation was complete. Ah, the dreaded documentation...
Brian shows how to use the factory-bean and factory-method descriptors in your ColdSpring XML file to handle automatic injection of beans obtained from factory objects that are also managed by ColdSpring. It's a powerful technique that helps completely remove a number of dependencies from your application code.
I use the same technique with Transfer and ColdSpring:
<bean id="transfer" factory-bean="transferFactory" factory-method="getTransfer" />
For the first role, we want someone who can create crisp, clean user interfaces that are intuitive and easy to use. You'll have good graphic design skills and the ability to take a UI vision and turn it into lightweight HTML + CSS, with slick JavaScript for interactivity. If you've got ColdFusion skills, that's a bonus.
For the second role, we want someone who can build high-performance, highly scalable ColdFusion systems. You'll have a good grasp of application frameworks and object-oriented development (preferably Fusebox + ColdSpring + Transfer since that's what we use - but experience with otherwise frameworks and a willingness to learn will count).
For both roles, you will be able to work independently (and remotely, if appropriate) but with a focus on delivery and collaboration. Familiarity with source code control (e.g., SVN) and bug tracking software (e.g., Trac) is a requirement.
It's early days for Scazu so we're looking for folks who can be creative about compensation in exchange for a stake in the company. Our collective success will mean you'll be in at the ground level and able to build your own teams over time so it's a great opportunity for the right folks!
You'll learn how we built the back end that supports several functions behind Acrobat Connect and Adobe Document Center - and Kuler - as well as some of our pain points and, in particular, the problems that arise when dealing with error handling around the boundaries of systems in a Service-Oriented Architecture.
I created a test case for parent / child bean factories and aliases, I put nothing but aliases in the child factories. ColdSpring couldn't find the aliases. I deduced (wrongly) that ColdSpring did not allow aliases in child factories to redefine beans in the parent factory.
Silly me. Turns out that my test case uncovered a bug in ColdSpring: aliases only work if the factory contains at least one real bean. At least, that's what my test cases seem to show. I'm going to run this past the ColdSpring crew for confirmation.
Want to share a single instance of Transfer between multiple Model-Glue applications?
Original code / post edited out.
The definition of transferFactory is in your parent bean factory which you tell Model-Glue about by putting this line in your index.cfm:
All the Model-Glue apps share that Application.cfc and so they all have the same parent bean factory which contains the single instance of the Transfer factory object. Each Model-Glue app has its own proxy object that delegates an alias that refers to the single factory object.
As someone who has contributed extensively to Mach II, Model-Glue, Fusebox, ColdSpring and Reactor (phew!), I would like to step up and defend Joe's decisions - he's done a sterling job, sticking to his vision for the framework and has been very clear about what should be in the framework and what should not. As a framework developer myself, I can tell you it's a rocky road. The "community" deluge you with requests for all sorts of features and you have to stand firm and defend your vision. None of the popular frameworks are "kitchen sink" efforts - there are countless feature requests that have been denied by the framework authors.
I've requested enhancements to all these frameworks. Some of those requests have been implemented but most have been denied. Even as lead developer on one of the Mach II releases, some of my suggested enhancements were turned down (and some of the changed Peter implemented in Mach II were reverted as inappropriate for the framework).
When I built Fusebox 5, I was deliberately very conservative about what went into the framework and what didn't. I implemented a few things the community really wanted that I didn't think were great ideas but I also did not implement several things that I thought were great ideas that the community weren't very interested in.
Fusebox 5.1 will be a fairly conservative enhancement release. Fusebox 6 has more scope for adding features but, even so, backward compatibility will be maintained and the addition of features will be strictly controlled but community-driven.
I don't know how community-driven Mach II is. I don't think it has a public bug tracker (Model-Glue, Fusebox, ColdSpring and Reactor all do). I get the impression that Application.cfc support was added for coolness (the other frameworks have taken great pains to remain compatible with CFMX 6.1 and equivalent competing ColdFusion engines).
Third, crack open Model-Glue and edit one of the core files - shock! horror! Edit ModelGlue/unity/config/Configuration.xml and change the definitions for ormAdapter and ormService as follows:
This defines what ORM service to use, such as Transfer.
-->
<bean id="ormAdapter" class="transfer.modelglue.TransferAdapter">
<constructor-arg name="framework">
<ref bean="ModelGlue" />
</constructor-arg>
</bean>
<!--
This defines the ORM service
-->
<bean id="ormService" class="transfer.TransferFactory">
<constructor-arg name="configuration">
<ref bean="transferConfiguration" />
</constructor-arg>
</bean>
Your Transfer configuration might look like this:
<constructor-arg name="datasourcePath">
<value>/environment/transfer/datasource.xml</value>
</constructor-arg>
<constructor-arg name="configPath">
<value>/environment/transfer/transfer.xml</value>
</constructor-arg>
<constructor-arg name="definitionPath">
<value>/environment/transferdata</value>
</constructor-arg>
</bean>
Joe and Mark and I are still looking at what it will take to support relationships with Transfer in Model-Glue. To be clear, Transfer has sophisticated support for relationships but Model-Glue's ORM support is very Reactor-centric right now which makes this level of integration somewhat more difficult!
I've talked before about the structure of our service-based system: we use ColdSpring to manage all of the model components; we have simple web service / Flash Remoting facades in front of that model; we share that configuration with our Model-Glue applications using the parent bean factory feature of ColdSpring. I've been focusing on the Model-Glue side of the things this week, so I thought I'd blog about how that's working out for us.
Big congratulations to Dave and Chris and the gang - this is an awesome piece of work!
From the video, you'll see that Unity uses Reactor to drive the database access and ColdSpring to manage both the Model-Glue service components and the Reactor factory itself. A very powerful combination!
Caveat: the documentation has not yet been updated so you may find yourself asking questions on the coldspring-dev mailing list!
I'll be presenting my "Managing ColdFusion Components with Factories" talk to BACFUG on May 17th (and then my "Objects and Persistence" talk on June 21st).
Adobe San Francisco, 601 Townsend, 7pm
The benefits of ColdFusion are slowing becoming apparent to my (formerly non-ColdFusion) colleagues: Java integration is fairly seamless, exposing code through web services or Flash Remoting is almost trivial, high-level tags that simplify integration tasks.
Within my overall team, I run a small group focused on core infrastructure and integration and we're getting into some prototyping work now and for that we're going to use Model-Glue to build quick HTML user interfaces and test harnesses and Reactor to simplify the data access layer, with a view to moving to custom SQL queries for performance later on. Given the ease of using ColdSpring with Model-Glue to manage the service layer, I strongly suspect we'll end up using all three frameworks together for our prototyping.
Over time we'll build out Flex 2 user interfaces, probably even for the internal administrative consoles that we might initially build using Model-Glue. The service layer we build should be directly reusable in that situation.
So far, the initial response to Model-Glue, ColdSpring and Reactor has been positive and we're looking forward to Model-Glue 2.0 a.k.a. "Unity".
I wrote a small Model-Glue / ColdSpring application that runs on her machine (which already runs the IRC bot) and lets her push files from the local financial folder tree to a specific directory on the remote website.
I figured it might be useful to someone so you can download the code from my software pod (right hand side of my blog).
Here's the code embedded in the web page on the regional website:
<cfset keys = structKeyArray(data) />
<cfset arraySort(keys,"text") />
<cfset n = arrayLen(keys) />
<cfloop from="1" to="#n#" index="i">
<cfoutput>
<p><a href="/data/#keys[i]#"><b>#keys[i]#</b></a><br />#data[keys[i]]#</p>
</cfoutput>
</cfloop>
To configure the app, edit filemanager/config/beans/beans.xml and change the local home directory and the remote server configuration.
The UI is very basic (hey, I'm an engineer not an artist!) and is modeled after the "webpush" utility Macromedia used to manage content on macromedia.com (with color-coding to indicate files that are the newer locally, the same, missing locally and missing remotely).
Anyway, if you find it useful, have fun with it. If nothing else, it's another example of using Model-Glue and ColdSpring together.
In your fusebox.xml file, you can define a fuseaction that is executed at application startup (on the first request after the application loads):
<appinit>
<fuseaction action="m.initialize" />
</appinit>
</globalfuseactions>
<cs:initialize />
<cs:loadBeans file="/config/beans/cs.xml" />
</fuseaction>
<constructor-arg name="configuration">
<value>/ggcc10/config/reactor.xml</value>
</constructor-arg>
</bean>
<bean id="taskGateway" factory-bean="reactorFactory"
factory-method="createGateway">
<constructor-arg name="objectAlias">
<value>task</value>
</constructor-arg>
</bean>
In the ModelGlue.xml file, specify the ColdSpring loader and that you want autowiring:
value="ModelGlue.Core.ColdSpringLoader" />
<setting name="autowireControllers" value="true" />
<cfargument name="gw" required="true" />
<cfset variables.taskGateway = arguments.gw />
</cffunction>
Magic!
Reactor is also getting some performance tweaks - some are already in the repository, more will be committed before cf.Objective() (do you see a pattern here?).
Check out the latest "BER" versions to try out the new abilities!
ColdSpring has recently been enhanced to support factory-bean and factory-method attributes in a bean definition so that you can declare beans that are actually created by external factories such as Reactor.
You declare the Reactor factory as a bean (managed by ColdSpring). Then you can declare DAO and gateway objects, in the ColdSpring XML file, which are created by the Reactory factory bean.
It's very slick.
However, most Reactor operations are focused on record objects which are transient (not singletons) and whilst those could be managed by ColdSpring, generally only singletons - per-application objects like services - should be managed by ColdSpring (since it adds a layer of complexity to object creation in order to leverage the power of the framework).
I was attempting to apply AOP to Reactor-generated objects so that I could simulate the security model in ggcc9 (the ninth variant of my frameworks comparison code - see the software pod on my blog). ColdSpring assumes that AOP-controlled objects are simple concrete classes and therefore it doesn't work with the nested inheritance hierarchy of the Reactor-generated DAO and gateway objects.
I did eventually make it work but it requires changes to ColdSpring and, for some of the autowiring I was doing, some changes to Model-Glue as well. I've submitted the patches to the revelant mailing lists for consideration but it means that I can't realistically release the ggcc10 variant's source code.
Despite my minor frustrations, the combination of the three frameworks is immensely powerful. If you look at the ggcc9 variant, you'll see it has several model CFCs and several bean CFCs. The ggcc10 variant has none of that. The model was really just DAOs and gateways which Reactor provides automatically and the beans become records which, again, Reactor manages automatically. About a dozen CFCs went away in the conversion. That's a lot of code I wouldn't have to write!
I added the following setting to ModelGlue.xml:
At some point I'll update this variant with the feedback I had from Chris Scott and/or Dave Ross who suggested (correctly) that the aspect should call the model and the actual check identity code should be there instead.
The thread continues to be interesting so watch the responses over the next day or two. In particular, I like Chris Scott's response that explains why he prefers setter injection (over constructor injection) and then he clarifies the potentially four-step object creation / initialization process that ColdSpring uses (it's much more sophisticated than I realized).
Matt's post talks about specific benefits of ColdSpring for Mach II developers and gives a good example (data source configuration). In particular he is "already seeing a huge benefit to doing things this way" and notes that using the two frameworks in combination "reduces complexity and increases flexibility". That may seem counter to your initial perception: after all, you need to learn another framework and deal with two XML files. I think he's right tho': it helps you focus on the two very different pieces of your application independently which means fewer moving parts to consider at the same time (Mach II for the controller; ColdSpring for the model).
Scott's post is typically more expansive, expressing his initial skepticism (ColdSpring looked like people pushing ColdFusion into the Java mold again) followed by a fairly enthusiastic adoption of ColdSpring. Scott already had some familiarity with the Java Spring framework, which helped him get up to speed. He gives some slightly more involved examples and gives the "MossyBlog stamp of approval".
So there you are: two frameworks together can be simpler than one framework on its own.
It's taken me a few reads to get my head around this and, right now, I don't know how I would use it in an application but it's good to know the functionality is there. I might look at revising the Model-Glue AutoWire controller to use ApplicationContext...
Naturally it's cat-related. I built the On Safari website last year (I am not responsible for the visual design!) using Fusebox and what little dynamic content I needed I was loading into the database from CSV files.
This year I decided to build a small content admin section to make this a more pleasant process as I add more content that people send me about past On Safari shows. For the admin, I decided to use Model-Glue, ColdSpring and Arf!
Code to fetch all the awards and sort them by year and sequence number:
<cfset var awardSelect = award.list(orderby="osyear DESC, seq ASC").getQuery() />
<cfset arguments.event.setValue("awards",awardSelect) />
Code to read in a single award record by ID:
<cfset var award = variable.rf.createRecord("admin.model.cataward") />
<cfif len(awardId)>
<cfset award.read(awardId) />
</cfif>
<cfset arguments.event.setValue("award",award) />
Code to save an award (either new or edited - Arf! knows that a blank ID means add a new record):
<cfset var award = variable.rf.createRecord("admin.model.cataward") />
<cfset var i = "" />
<cfloop list="#fields#" index="i">
<cfinvoke component="#award#" method="set#i#">
<cfinvokeargument name="#i#" value="#arguments.event.getValue(i,'')#" />
</cfinvoke>
</cfloop>
<cfset award.save() />
<cfset arguments.event.addResult("success") />
And, finally, code to delete an award:
<cfset var award = variable.rf.createRecord("admin.model.cataward") />
<cfset award.setId(awardId) />
<cfset award.delete() />
<cfset arguments.event.addResult("success") />
You can decide for yourself how much work this saves. The cataward CFC is essentially empty (just the Arf! template). It was certainly nice not having to write CRUD SQL but in an app this size there wouldn't be very much of it.
It works, it's reasonably fast - certainly fast enough for my little admin needs.
What could I do better? Well, I ought to have a separate DAO layer and isolate the use of Arf! inside that rather than just manipulating Arf! in my controller but I just wanted a quick'n'dirty content admin. I'm only using ColdSpring to create and load the Arf! Datasource and RecordFactory objects (overkill but convenient). I'm using the autowire feature (in the ColdSpring CVS version, not yet released).
That means that the Model-Glue / ColdSpring integration will be as simple as:
Specify the ColdSpring bean factory loader and location of the ColdSpring bean definition file in ModelGlue.xml:
<setting name="beanMappings" value="/ggcc9/config/beans/ggcc.xml" />
<controller name="csaw" type="coldspring.modelglue.AutoWire"/>
...other controllers...
</controllers>
In order to try it out you will need the BER of Model-Glue (which has Joe's latest ColdSpring integration), the 0.2.1 release of ColdSpring which includes both AOP and the Model-Glue adapter from Dave Ross, and you will also need this extension to ColdSpring that adds auto-wiring for Model-Glue controllers.
In this variant, ColdSpring manages all of the model (except the transient note, task and user beans - I may convert these later) and it also autowires the various beans into the controller objects at startup (so the controller objects have no internal initialization code!).
I've also modified how security is managed to use ColdSpring AOP. In the previous Model-Glue variant (#7), security was checked explicitly in various event handlers by broadcasting the checkIdentity message. Now it is handled through "before advice" on the taskDAO and taskGateway objects, using ColdSpring AOP. The advice performs the security check and throws an exception if the user is not logged in. In the exception event handler, a message is broadcast that causes event results to be set if the exception can be handled by another event (in this case the security exception can be handled by the ggcc.identify event, which challenges the user to login).
I think this shows the power of these two frameworks in combination!
The simple answer is because it doesn't know about your application framework so it doesn't know about controllers.
Dave Ross and Chris Scott are working on a plugin for Mach II that will allow ColdSpring to automatically locate the listeners, plugins and filters in your "controller" and look for setXxx(yyy) methods in them. If it can match a setter to a bean that it knows about (from the ColdSpring bean XML file), it will automatically invoke the setter for you.
I thought that was a great idea but I wanted it for Model-Glue!
So I wrote an AutoWire.cfc for Model-Glue. It relies on Joe's BER changes to Model-Glue to support the ColdSpring bean loader. I've submitted it to Joe, Dave and Chris so hopefully it will be incorporated at some point.
How it works: Model-Glue creates the bean factory, then creates the controllers. With the ColdSpring changes that Joe listed, Model-Glue creates the ColdSpring bean factory instead of its own (ChiliBeans). My AutoWire.cfc is a controller that you declare in the XML (as the first controller). At startup, when Model-Glue creates that it, AutoWire then modifies the in-memory Model-Glue object so it can intercept subsequent controller creation. Then, as Model-Glue creates the remaining controllers, AutoWire searches for setXxx(yyy) methods on each one and attempts to match them to beans declared in the ColdSpring XML file.
If anyone is desperate to try this out, I'm happy to send you the work-in-progress code...
I was able to remove the ColdSpring bean factory 'hack' from my controller (see link to Dave Ross's post in my previous entry) and just make the ModelGlue.xml changes that Joe mentions. Using ColdSpring is now so easy with Model-Glue that I expect this is how I'll be building applications moving forward!
Dave Ross shows how to use the Model-Glue adapter in ColdSpring - the returnType= attribute should actually specify the fully-qualified return type tho'. That combined with Chris Scott's AOP tutorial and a quick read of the source code (download from coldspringframework ).
My LoggingAfter CFC extends coldspring.aop.AfterReturningAdvice, implements afterReturning() which logs a message and then returns arguments.returnVal (very important!).
My ColdSpring XML file specifies:
- xxxTarget - my actual bean that I want to log methods in
- xxx - a coldspring.aop.framework.ProxyFactoryBean that references xxxTarget and uses the logAfterAdvisor intercepter (below)
- logAfterAdvice - my simple logging class
- logAfterAdvisor - a coldspring.aop.support.NamedMethodPointcutAdvisor that specifies my logAfterAdvice as the advice property and * as the mappedNames (matches anything)
The results of calling methods in xxxTarget are logged automatically!
Logging can be disabled by renaming the xxx and xxxTarget beans (so that my application code calls the actual bean, via the name xxx, instead of the proxy).
Very slick...
Update: see the next blog entry for an even simpler integration!
The #coldfusion channel is often all over the shop and sometimes politically incorrect in the extreme but the framework-related channels are generally much quieter and much more on-topic.
Well, assuming your application is built with ColdSpring in the first place - which is reason enough to start looking seriously at using ColdSpring to assist in managing objects in your Model.
ColdSpring AOP lets you "re-wire" the objects in your Model so that your code ends up calling proxy objects (which in turn call your original objects), and the proxy objects can execute "advice" code before, after or around calling the original methods. This lets you add logging to all or any part of your application, simply by configuring the XML file that defines the objects that ColdSpring manages. Or security. Or...
I've already added a comment in response to several other comments there but I want to highlight a couple of observations he makes.
He draws a clear distinction between the primary application frameworks (Fusebox, Mach II, Model-Glue) and the "supporting" frameworks (Tartan, CFHibernate, ColdSpring). This is important to understand: you can use the supporting frameworks on their own, i.e., with your own ad hoc code, but they really work well when used with the primary application frameworks. Indeed, Tartan includes a Mach II listener and Model-Glue includes a Tartan proxy.
He also notes that Mach II gives the appearance of a framework that is not evolving very fast and compares it to Model-Glue, saying the latter "might very well take over". It will definitely be an area to watch closely.
More on this topic when I speak at SacCFUG, BACFUG, CFUNITED and PDXCFUG over the next few months. After CFUNITED, I'll make seven variants of a sample application available - each variant shows a different framework or a different style within a single framework.


