|
From: Colin S. <col...@ex...> - 2004-01-07 21:57:42
|
Hi Peter,
BeanPostProcessors are a function of ApplicationContexts, so it is
normal that BeanFactories which are not also ApplicationContexts (such
as that produced by XMLBeanFactoryLoader) do no post-processing.
However, I do agree that the differences betweeen plain BeanFactories
and ApplicationContexts should probably be better documented, and the
XMLBeanFactoryLoader should state that it produces a BeanFactory, not an
ApplicationContext. Alternately, it could possibly produce an
ApplicationContext.
fyi, I currently override the default BeanFactoryLoader in my ejbs, as
follows:
setBeanFactoryLoader(new BeanFactoryLoader() {
public BeanFactory loadBeanFactory() throws BootstrapException {
ContextLocator cf = ContextLocatorFactory.getInstance();
ApplicationContext appContext =
cf.useContext(ServicesConstants.CONTEXT_GROUP_KEY,
ServicesConstants.PRIMARY_CONTEXT_ID);
return appContext;
}
public void unloadBeanFactory(BeanFactory bf) throws
FatalBeanException {
}
});
This relies on my own ContextLocator interface/impl, to actually load in
on-demand, a hierarchy of ApplicationContexts.
Regards,
Colin
Peter den Haan wrote:
> One thing that recently confused the heck out of me was that my AOP
> interceptors wouldn't work in an EJB context (1.0M4). Advice simply
> wasn't being applied to my beans even though precisely the same
> configuration worked fine in the web tier. Given that
> DefaultListableBeanFactory does contain the full BeanPostProcessor
> infrastructure, I didn't see how that could be.
>
> Upon closer examination, it turned out that the bean factory does not
> initialise its own BeanPostProcessors. Instead,
> AbstractApplicationContext does this by pulling all beans implementing
> BeanPostProcessor out of the factory and registering them in order
> before any of the other beans get instantiated. The
> XmlBeanFactoryLoader used by the EJB support classes, on the other
> hand, does no such thing. (Something similar can be said about
> BeanFactoryPostProcessors. Unless I'm missing something, this
> interface receives support only in an application context and has no
> bean hierarchy support at all.)
>
> Given that more and more of Spring's infrastructure relies on
> postprocessing, the BeanFactory support in AbstractEnterpriseBean
> seems crippled unless you roll your own XmlBeanFactoryLoader along the
> lines of attached class. We could do any of a number of things with this.
>
> * BeanPostProcessor registration could be made a responsibility of
> DefaultListableBeanFactory, although this might break existing
> software. I assume there's a good reason why this is an context
> rather than a factory responsibility.
> * A new loader along the lines of attached file could be added to
> the framework, and should probably used by default in
> AbstractEnterpriseBean. Wholesale cutting and pasting from
> AbstractApplicationContext can be avoided by migrating
> BeanFactoryPostProcessor and BeanPostProcessor registration to
> either a utility class or to utility methods in
> DefaultListableBeanFactory (these would not be part of the
> normal factory refresh, but would have to be invoked explicitly).
> * Instead of creating a new loader, BeanPostProcessor registration
> could simply be incorporated into XmlBeanFactoryLoader itself.
> * Everything could be left as is. In that case I feel the
> restrictions of bean support in a plain factory (as in EJBs)
> should be very clearly documented, otherwise this is going to
> confuse and discourage quite a few people.
>
> Thanks for reading as far as this :) Let me know what you think. I
> would be more than happy to supply patches for the above against the
> current CVS head.
>
> - Peter
>
>
|
|
From: Peter d. H. <pe...@de...> - 2004-01-07 22:44:31
|
Colin Sampaleanu wrote: > BeanPostProcessors are a function of ApplicationContexts, so it is > normal that BeanFactories which are not also ApplicationContexts (such > as that produced by XMLBeanFactoryLoader) do no post-processing. Ah, but that's the funny thing. This is not entirely true. The actual postprocessing plumbing is part and parcel of the DefaultListableBeanFactory itself. However, it does not auto-register any postprocessors itself. That is done by the application context. Given the important place postprocessing has been gaining in the Spring infrastructure, it seems odd that EJBs do get a BeanFactory that does in fact have all it takes (you do not need a full context) but is still very limited because its postprocessing plumbing isn't initialised. Users new to the product would expect Spring to provide some out-of-the-box support for a fully functional bean container in the EJB tier, probably by default. As things stand, you won't be getting this without coding (and a nontrivial understanding of Spring subtleties). - Peter |
|
From: Colin S. <col...@ex...> - 2004-01-07 22:58:56
|
Peter den Haan wrote: >Colin Sampaleanu wrote: > >>eanPostProcessors are a function of ApplicationContexts, so it is >>normal that BeanFactories which are not also ApplicationContexts (such >>as that produced by XMLBeanFactoryLoader) do no post-processing. >> >> >Ah, but that's the funny thing. This is not entirely true. The actual >postprocessing plumbing is part and parcel of the DefaultListableBeanFactory >itself. However, it does not auto-register any postprocessors itself. That >is done by the application context. Given the important place postprocessing >has been gaining in the Spring infrastructure, it seems odd that EJBs do get >a BeanFactory that does in fact have all it takes (you do not need a full >context) but is still very limited because its postprocessing plumbing isn't >initialised. > >Users new to the product would expect Spring to provide some out-of-the-box >support for a fully functional bean container in the EJB tier, probably by >default. As things stand, you won't be getting this without coding (and a >nontrivial understanding of Spring subtleties). > > The fact that DefaultListableBeanFactory has some of the support code is somewhat irrelevant. The contract is that if something has the ApplicationContext interface it supports BeanPostProcessors, and if it doesn't (i.e. it is simply a BeanFactory), it doesn't support BeanPostProcessors. And this is how the current code behaves. As I said, I agree that the distinction between application contexts and bean factories needs to be better documented, and it probably makes sense for the default BeanFactoryLoader in the base EJB classes to produce an ApplicationContext variant instead of just a regular BeanFactory. That code actually got into Spring before I got to the project, so I'm not sure why it was decided one way vs. another. If there is no opposition, I am quite willing to make that change... Regards, Colin |
|
From: Peter d. H. <pe...@de...> - 2004-01-07 23:13:30
|
Colin Sampaleanu wrote: > The fact that DefaultListableBeanFactory has some of the support code is > somewhat irrelevant. The contract is [...] My apologies, I wasn't at all clear. Although I listed changing way the BeanFactory works as the first possibility, I don't think that's by any means the best option. Changing the contract might break existing software and would not be a good idea at this stage even if it were desirable as such. The basic need is for the postprocessors in the BeanFactory to be initialised; either by modifying XmlBeanFactoryLoader to perform this initialisation, or through replacing the BeanFactory with a full ApplicationContext as you suggest. That would be an even better solution but slightly more of a change. I'd be happy with either :) Thanks - Peter |
|
From: Colin S. <col...@ex...> - 2004-01-18 00:20:12
|
As per the thread below from about a week ago, I have defaulted AbstractEnterpriseBean and its subclasses to use a new XmlApplicationContextBeanFactoryLoader, which will load and create an ApplicationContext from the classpath. For a lighter weight solution when ApplicationContexts are not needed, people may still switch in the old XmlBeanFactoryLoader. One comment though, is that if you look at a common usage scenario, which is to call out from Session ejbs to service POJOs using Hibernate-based DAO/Mapper objects, this solution is still not good enough, in that every EJB ends up creating an application context, which ends up creating a new session factory for every EJB. For this reason, I still drop in a custom BeanFactoryLoader which loads/accesses a shared ApplicationContext via the KeyedSingletonContextLocator I posted here a while ago. Regards, Colin Colin Sampaleanu wrote: > Peter den Haan wrote: > >> Colin Sampaleanu wrote: >> >>> eanPostProcessors are a function of ApplicationContexts, so it is >>> normal that BeanFactories which are not also ApplicationContexts (such >>> as that produced by XMLBeanFactoryLoader) do no post-processing. >>> >> >> Ah, but that's the funny thing. This is not entirely true. The actual >> postprocessing plumbing is part and parcel of the >> DefaultListableBeanFactory >> itself. However, it does not auto-register any postprocessors itself. >> That >> is done by the application context. Given the important place >> postprocessing >> has been gaining in the Spring infrastructure, it seems odd that EJBs >> do get >> a BeanFactory that does in fact have all it takes (you do not need a >> full >> context) but is still very limited because its postprocessing >> plumbing isn't >> initialised. >> >> Users new to the product would expect Spring to provide some >> out-of-the-box >> support for a fully functional bean container in the EJB tier, >> probably by >> default. As things stand, you won't be getting this without coding >> (and a >> nontrivial understanding of Spring subtleties). >> >> > The fact that DefaultListableBeanFactory has some of the support code > is somewhat irrelevant. The contract is that if something has the > ApplicationContext interface it supports BeanPostProcessors, and if it > doesn't (i.e. it is simply a BeanFactory), it doesn't support > BeanPostProcessors. And this is how the current code behaves. As I > said, I agree that the distinction between application contexts and > bean factories needs to be better documented, and it probably makes > sense for the default BeanFactoryLoader in the base EJB classes to > produce an ApplicationContext variant instead of just a regular > BeanFactory. That code actually got into Spring before I got to the > project, so I'm not sure why it was decided one way vs. another. If > there is no opposition, I am quite willing to make that change... > > Regards, > Colin > |