roller-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Denis Balazuc <de...@balazuc.net>
Subject Re: Spring Roller
Date Thu, 07 Jun 2007 21:58:10 GMT
Hi all !

Anyone had time to have a quick look at this?
I'd love to get some feedback, see if I should carry on in that 
direction (I'd be more than happy to!)

Thanks a lot
Denis Balazuc


Denis Balazuc wrote:
> Hello all
> 
> I've finally found some time to tidy up a Spring demo for Roller.  I've 
> tried to include various different aspects of what Spring can bring into 
> a project such as Roller (depency injection, interceptors and 
> transaction management mostly) and focused on easy back-end switch and 
> simple configuration for the mail and the main datasource. There are 
> many areas that I didnt address but where I can see some benefits from it.
> 
> #Journey onward with Spring!
> 
> Before going further, I would like to mention that, with ACEGI already 
> at the source of the security model of the Roller webapp, it was easy to 
> convince myself that introducing Spring in the business layer was just a 
> natural continuation of the work that's already been done  there and a 
> good goal to pursue. Besides only addressing the back-end, there is a 
> lot that can be done on the webapp side too. So...Spring's already 
> there, temperature's getting good....let's go!
> 
> A few first things
> 
> * File(s) URL are at the end of this mail. For the impatients, it's 
> better to read from the bottom to the top.
> 
> * When mentionning classnames or other code details, I will be referring 
> to version 541334 of the trunk, which is before refactoring of the pojos 
> and right in the middle of the creation of the /component directory. 
> Classnames and details discussed hereunder may be slighty out of date. I 
> also did not consider Planet as I reckoned that most of what is involved 
> applies to Planet the exact same way, and RollerConfig (which should be 
> trivial to Springify) to avoid getting in the midst of 
> too-much-changes-at-once.
> 
> * version 541334 has a few problems with creating new entries or categories
> If you ever happen to want to try to run my build, expect a few things 
> to not work correctly, including things I've probably destroyed along 
> the way. Having everything pristine is not the goal of this demo and 
> code has moved since so it really did not really matter.
> 
> * I haven't tested all of everything, some bits hereunder are also 
> theory only, but those are not rocket science to implement despite my 
> hidden kid desire to be a rocket scientist.
> 
> #Mail and DataSource
> 
> First thing, I wanted to address the problem of switching the mail 
> session and the datasource, from JNDI to plain good auld java code or 
> others.  Spring allows you to switch those implementations without code 
> that will fetch a property, check which of JNDI or plain mail session 
> (or jdbc datasource) to use, and so forth. Surely it requires injecting 
> a bean or some lookup code. For that, I have modified MailUtil.java and 
> re-implemented DataProvider.java to use a Spring bean. In the case of 
> MailUtil.java, a Spring interface, JavaMailSender is being used 
> internally in place of a javax.mail.Session instance. In the case of 
> DataProvider.java, Spring actually makes it obsolete as it can provide a 
> datasource bean from configuration so its implementation looks up for a 
> datasource bean.
> An interesting note is that the roller(-custom).property switch 
> (depending on the "database.configurationType" property) is implemented 
> within the Spring configuration, removing the need for the various 
> service providers or factories within the code.
> This also shows how it's possible to move a lot of configuration logic 
> out of the code and into XML files that usually never change.
> 
> See
> src/applicationContext-rollerMail.xml
> src/applicationContext-rollerDatasource.xml
> 
> #"Back-end" implementation
> I got caught in the middle of JPA changes while doing this work, 
> so....switching back-end sounded like a good target for dependency 
> injection. We have interfaces, we have implementation classes, ideal 
> conditions for a lift-off!
> RollerImpl.java has been modified and merged from 
> HibernateRollerImpl.java so it contains ALL the Roller manager 
> implementations. Those are injected through 
> src/org/apache/roller/business/applicationContext-business.xml using 
> either common beans for the managers that do not have links to the 
> database, either back-end implementation specific beans (Hibernate, JPA, 
> all you can invent). Of course, the singleton nature of those 
> implementations is preserved where required.
> 
> See 
> src/org/apache/roller/business/applicationContext-business-hibernate.xml
> 
> This allows for
> 
> -- Switching back-end implementations such as Hibernate, JPA or unit 
> test mocks/stubs easily.
> 
> -- Adding declarative transaction management and remove the need for the 
> code to worry about that aspect which in Roller impersonates as the 
> "HibernatePersistenceStrategy". In that particular matter, there would 
> be a lot to discuss about the current implementation of the Hibernate 
> layer using the HibernatePersistenceStrategy and the different approach 
> that is, somewhat unfortunately, required to take when going the Spring 
> way. For instance, the usage of Spring's HibernateTemplate or 
> HibernateCallback(s) are encouraged, effectively tying the DAO code to 
> Spring, but also moving the transaction headaches to configuration. As a 
> developer, I tend to favor the fact that I do not have to worry about 
> transactions or such horrible things, and leave those headaches to those 
> who integrate with various systems. Being able to do it by configuration 
> is a good plus.
> 
> -- Ungluing the implementation code and allowing the removal of 
> HibernateRollerImpl and friends, since each single manager is a 
> different Spring bean, maybe sharing common attributes (such as the 
> HibernatePersistenceStrategy). Those beans are injected in the 
> RollerImpl facade, which allows for easy switching when, for example, 
> unit test comes in the loop.
> 
> -- In the very interesting case of the ThreadManager, and more generally 
> the scheduling of tasks, my first thought went about what's going to 
> happen to application managed thread pools or schedulers in a strict 
> J2EE environment. If you intend to run Roller in a J2EE 1.4 containers, 
> you may want to use container-managed thread pools, or WorkManager(s) or 
> other Websphere-like WorkArea(s) and Scheduler(s). Since you can, 
> transparently to the code, lookup an EJB or provide a home-grown 
> implementation of a ThreadFactory/ExecutorService/etc, Spring is very 
> much welcomed here. As an example. the switch from ThreadFactory to 
> ExecutionService(s) in the branches after the one I was working one can 
> be performed from configuration, with a small changes in the 
> ThreadManagerImpl code to allow injection.
> 
> #Property loading
> As mentionned above, Spring makes it easy to load various property 
> sources. Spring configuration files may also reference property values 
> using the  usual ${value} syntax, which is what is used to populate 
> properties among the various manager beans and, among many, provide the 
> datasource parameters depending on the roller.properties and 
> roller-custom.properties. Again, RollerConfig wasn't taken into 
> consideration but it's easy to adapt its implementation to fetch its 
> properties from Spring.
> 
> see src/applicationContext-rollerProperties.xml
> 
> #Conclusion
> I'm not great a concluding so here's some more concrete material
> 
> #Files and reference
> 
> I've packed some demo code within the following files. I decided against 
> providing a really functional patch to submit to JIRA since my code 
> baseline is already old compared to the recent changes for 4.0 and this 
> whole thing is just a proof of concept.
> 
> 
> *
> http://denis.balazuc.net/roller/roller_541344-spring-stable.zip
> (1) That's the Roller code my build is based on (from version 541344 of 
> the trunk). Much too big (150Mb) to download and messed up since it's my 
> working copy, but well...
> 
> *
> http://denis.balazuc.net/roller/roller_541344-spring-stable-webapp.zip
> My current test web app only (Roller - no Planet) with all JAR files but 
> exploded roller-*.jar for reference (25Mb)
> 
> 
> *
> http://denis.balazuc.net/roller/roller_541344-spring-stable-webapp-nojars.zip 
> 
> My current test web app only (Roller - no Planet) without any JAR file 
> and exploded roller-*.jar for reference (6.7 Mb)
> 
> 
> *
> http://denis.balazuc.net/roller/roller-trunk-541344-spring-patch.txt
> Patch made from (1) from trunk version #541344. You will still need the 
> JAR files listed above. I"m not very familiar with patching so it might 
> not be reliable.
> 
> 
> First things you may want to look at are the Spring configuration files
> (it's not XML hell, honest)
> 
> /src/applicationContext-rollerProperties.xml
> /src/applicationContext-rollerMail.xml (used in MailUtil.java)
> /src/applicationContext-rollerDatasource.xml
> 
> /src/applicationContext-roller.xml
> /src/org/apache/roller/business/applicationContext-business.xml
> /src/org/apache/roller/business/applicationContext-business-hibernate.xml
> 
> 
> #Build considerations
> I had to replace a few JAR files with new ones and created
> /tools/spring-2.0.5
> /tools/spring-2.0.5/acegi-security-1.0.3.jar
> /tools/spring-2.0.5/ehcache-1.2.4.jar
> /tools/spring-2.0.5/spring.jar
> 
> 
> #More files for the curious
> 
> * There is a
> /src/org/apache/roller/business/applicationContext-business-hibernate2.xml
> along with its own hibernate2 implementation package, which uses a 
> Hibernate SessionFactory provided by Spring and delegating transaction 
> management to the configuration, rather than implementing a specific 
> "strategy". This setting is not currently working as it would require a 
> different approach on DAOs. The provided example shows how transaction 
> management could be done, but ideally, Spring's HibernateTemplate and 
> HibernateCallback(s) should be used to perform simple unit of (database) 
> work within a transaction into the Hibernate implementation layer if 
> Spring is to be exploited with its full potential.
> 
> * The file 
> /src/org/apache/roller/business/applicationContext-business-jpa.xml is 
> not functional at all but exists for the sole purpose of demonstrating 
> how painlessly implementations can be switched if required.
> 
> 
> **
> http://denis.balazuc.net/roller/blug-project-demo.zip
> This is a personal project I had started after Struts-ifying Pebble 
> (http://pebble.sourceforge.net/), which still serves my wife's blog 
> nicely but needs replacement, and before meeting Roller. Most of the 
> Spring ideas exposed here come from there. I've tried to separate the 
> DAO and business layers in various projects, which helps leveraging 
> Spring's benefits.
> 
> Cheers
> Denis Balazuc
> 

Mime
View raw message