Allen Gilliland wrote:
On Mon, 2006-03-06 at 15:06, Sean Gilligan wrote:
Allen, I definitely recommend that you at least spend a couple of hours looking at Spring for distributed transactions and pluggable ORM layers before going ahead with your proposed refactoring of the transaction code.

I will certainly do that, but this may be the realm where I would be least 
likely to start using a framework like Spring.
In many ways, Spring is the "un-framework". The developers try really hard to allow you to minimize or avoid altogether dependencies on the framework, as well as give you choices "a la carte" rather than force/push you to adopt everything. Many commercial offerings (for obvious reasons) encourage you to depend on their product/API in as many ways as possible. The same is true for many Open Source projects as well, as it is only human to want the product of your labor to solve as many problems as possible. In the Spring Framework, I see a concerted effort and a philosophy of resisting this urge as much as possible.

 My main concern is that we would move away from our own implementation of 
Hibernate and into a version of Spring Hibernate, doing Hibernate the way 
Spring suggests.
My (limited) understanding of how Spring works at this layer is that you can use Springs declarative transactions as method interceptors on top of just about any DAO layer or service object and that you don't have to use the Spring Hibernate Templates to do this.

In other words, *I think* you could use Spring Declarative Transactions without moving away from Roller's current implementation of Hibernate. I'm not sure that this will work, though. My experience has been using the default Spring+Hibernate+Declarative-Transactions implementation. Anil, Matt, do you guys have any guidance here?

The key to using Spring Declarative Transactions is to wrap existing Dao/Manager/Service Objects with the "TransactionProxyFactoryBean", which implements the pre/post method-call magic to implement the transactions. This means that whatever is using the Managers should be getting the implementation from BeanFactory, so this is one change that would be required in the Roller code. A side benefit to this change is that the same mechanism used to install the proxies is the mechanism used to plug in other manager implementations.

Now the proxies need to have a TransactionManager injected and Spring provides a HibernateTransactionManager, which in turn requires (via D.I.) a Hibernate SessionFactory. I don't know what would be involved in "sharing" a SessionFactory between the current Roller code and these Spring components. Anil, Matt?

>> If you really wanted to keep certain beans
restricted to a particular layer or module, that module could have a private BeanFactory that the other components are not aware of. In other words they won't be able to get access to the "ctx" variable/reference. (In my opinion, this shouldn't be necessary.)

Hmm.  That sounds promising to me.  I'd like to hear more about that.

I've never done this before, but believe it should be possible. Most Spring apps tend to use a single (Web)ApplicationContext (which is a subclass of BeanFactory) that is a single context (container). Most apps break up the layers (Presentation, Service, Data) into separate configuration files, but objects from all layers are (theoretically) obtainable by any component that has a context reference. (Although, as Anil says, using a context reference is to be avoided in favor of DI.)

So you should be able to allocate a private BeanFactory in the Business or Persistence layer that nothing else is aware of. (By just choosing a constructor that points to a config file or resource and stuffing the context away somewhere.)

I'm willing to look into this further if that will help you.

This is the other big thing that I am concerned about with Spring in
Roller.  I really don't want go back to making the config more
complicated and spread out.
This is a valid concern and one that Spring doesn't automatically address. And there is an inherent trade-off in making components more modular vs. keeping configuration simple and in one place. Anil (and the team) should address these issues in any proposal(s).

I think at this point I am also just having a bit of fun giving you guys a hard 
time about your attempts to get Spring into Roller ;)

Hah! The camel's nose is already in the tent, via Acegi! Resistance is futile! ;)

Seriously, though, the Spring Framework (or un-framework) is modular and adopting it is not an all-or-nothing decision. There are multiple ways that it could help (or hurt, if misused) Roller. Each one should be carefully analyzed and discussed and the possible answers are "yes", "no", and "yes, but here's a better way...". We should pay careful attention to issues of configuration and the trade-off between modularity and complexity. It is important to distinguish between implementing (or refactoring) a module to use IOC/DI vs. implementing an interface vs. extending a class. It's good that you're playing the role of the skeptic here, it will result in better designs.


Cheers,

Sean

Reply via email to