-
1. Re: Generalizing dependency injection
alesj Mar 7, 2008 11:43 AM (in response to starksm64)"scott.stark@jboss.org" wrote:
I'm fuzzy on the bean factory details in terms of whether the pooling is something that can live in the mc code.
To repeat my 'proposal' more publicly.
I don't know how much this would help, but we can make our MC beanfactory more flexible by doing something like this:
e.g. able to change the underlying impl class from GenericBeanFactory to anything that implments BeanFactory
And I would also change the BeanFactory.createBean() method signature to createBean(Object... args).
Being able to pass in additional information when creating/pooling bean.
And we wouldn't be breaking any previous beanfactory usage. -
2. Re: Generalizing dependency injection
wolfc Mar 11, 2008 6:58 AM (in response to starksm64)Business interfaces can be implemented by multiple beans, so there must be a clarifier in between.
+ "ejb/" + vfsPath + local-interface name + "/" + ejbName
should work.
If we then get a non-deterministic injection we can throw an exception.
Why not reverse it a bit:
+ "ejb/" + local-interface name + vfsPath + "/" + ejbName
then traversal is a bit easier in case multiple jars within one ear contain the same interface. -
3. Re: Generalizing dependency injection
starksm64 Mar 11, 2008 11:15 AM (in response to starksm64)"wolfc" wrote:
Business interfaces can be implemented by multiple beans, so there must be a clarifier in between.
+ "ejb/" + vfsPath + local-interface name + "/" + ejbName should work.
If we then get a non-deterministic injection we can throw an exception.
Why not reverse it a bit:
+ "ejb/" + local-interface name + vfsPath + "/" + ejbName
then traversal is a bit easier in case multiple jars within one ear contain the same interface.
Working through the resolution implementation more, we want a simple lookup to resolve a reference, so the ejbName of the providing cannot be part of at least one form of the key. That is an unknown element from the point of view of the referencer. We need multiple keys for each provider, some of which may be non-unique.@EJB(beanInterface=X.class)
translates to a lookup of the provider "ejb/X". If we have multiple providers of the X interface, only the first to be processed would be the provider? If we want to fail an attempt at injection of a non-unique provider, we would have to track the duplicate providers to thrown an exception with the duplicates.@EJB(beanInterface=X.class, name="XBean")
translates to a lookup of "ejb/X/XBean". The ejb-name is only unique within an ejb-jar, so here again we can have duplicates sources matching this key.@EJB(beanInterface=X.class, name="some.jar#XBean")
translates to a lookup of "ejb/X/some.jar/XBean". This is the only guaranteed unique key within a deployment. -
4. Re: Generalizing dependency injection
wolfc Mar 12, 2008 7:38 AM (in response to starksm64)"alesj" wrote:
"scott.stark@jboss.org" wrote:
I'm fuzzy on the bean factory details in terms of whether the pooling is something that can live in the mc code.
To repeat my 'proposal' more publicly.
I don't know how much this would help, but we can make our MC beanfactory more flexible by doing something like this:
e.g. able to change the underlying impl class from GenericBeanFactory to anything that implments BeanFactory
And I would also change the BeanFactory.createBean() method signature to createBean(Object... args).
Being able to pass in additional information when creating/pooling bean.
And we wouldn't be breaking any previous beanfactory usage.
What would the args be? -
5. Re: Generalizing dependency injection
wolfc Mar 12, 2008 7:57 AM (in response to starksm64)"scott.stark@jboss.org" wrote:
Working through the resolution implementation more, we want a simple lookup to resolve a reference, so the ejbName of the providing cannot be part of at least one form of the key. That is an unknown element from the point of view of the referencer. We need multiple keys for each provider, some of which may be non-unique.@EJB(beanInterface=X.class)
translates to a lookup of the provider "ejb/X". If we have multiple providers of the X interface, only the first to be processed would be the provider? If we want to fail an attempt at injection of a non-unique provider, we would have to track the duplicate providers to thrown an exception with the duplicates.
Exception if there are multiple providers are found in the same ear."scott.stark@jboss.org" wrote:
@EJB(beanInterface=X.class, name="XBean")
translates to a lookup of "ejb/X/XBean". The ejb-name is only unique within an ejb-jar, so here again we can have duplicates sources matching this key.
We are talking MC lookups here, right?"scott.stark@jboss.org" wrote:
@EJB(beanInterface=X.class, name="some.jar#XBean")
translates to a lookup of "ejb/X/some.jar/XBean". This is the only guaranteed unique key within a deployment.
And I say reverse the bind. So the bind becomes:
"ejb/X/some.jar/XBean"some.jar: class TestBean { @EJB X a; }
Hooks java:comp/env/TestBean/a to MC "ejb/X/some.jar" (which is a map). If the during injection the map contains more than 1 item, exception.@EJB(beanName="XBean") X b;
Hooks java:comp/env/TestBean/b to MC "ejb/X/some.jar/XBean".@EJB(beanName="other.jar#XBean") X c;
Hooks java:comp/env/TestBean/c to MC "ejb/X/other.jar/XBean".
Note: 'name' is something else:@EJB(name="x", beanName="XBean") X d;
Hooks java:comp/env/x to MC "ejb/X/some.jar/XBean". -
6. Re: Generalizing dependency injection
alesj Mar 12, 2008 11:22 AM (in response to starksm64)"wolfc" wrote:
What would the args be?
Anything you like. :-)
Making it a bit more portable.
But then again, if you were able to change the underlying beanfactory impl, you could always introduce your own interface. -
7. Re: Generalizing dependency injection
wolfc Mar 13, 2008 5:15 AM (in response to starksm64)I think we need to separate injection and component construction (/destruction).
It seems we're forgetting again that a component class = 1 bean class + interceptor classes. So interceptor lifecycle is tied to the bean. While injection follows the same rules.
At the end of the day I want to have something like:package org.jboss.ejb3.pool; /** * Creates and destroys stateless objects. * * The object returned by create has dependencies injected. The PostConstruct * callback, if defined, has been called. * * @author <a href="mailto:carlo.dewolf@jboss.com">Carlo de Wolf</a> * @version $Revision: $ */ public interface StatelessObjectFactory<T> { /** * Creates a new stateless object by calling it's empty constructor, * do injection and calling post-construct. * * @return */ T create(); /** * Perform any cleanup actions on the object, such as * calling the pre-destroy callback. * * @param obj the object */ void destroy(T obj); }
http://viewvc.jboss.org/cgi-bin/viewvc.cgi/jbossas/projects/ejb3/trunk/pool/src/main/java/org/jboss/ejb3/pool/StatelessObjectFactory.java?view=markup
Behind the scenes it delegates to 'bean factory' for construction which delegates to injection for each object which is part of the component. -
8. Re: Generalizing dependency injection
starksm64 Mar 13, 2008 5:36 AM (in response to starksm64)An extension of org.jboss.beans.metadata.spi.factory.BeanFactory is needed:
public interface BeanFactory { /** * Create bean. * * @return bean * @throws Throwable for any error */ Object createBean() throws Throwable; } public interface PooledBeanFactory extends BeanFactory { destroy(Object instance) throws Throwable; }
-
9. Re: Generalizing dependency injection
adrian.brock Mar 13, 2008 9:21 AM (in response to starksm64)I thought EJB3 used its own thread local pooling to avoid contention?
Personally I think object pooling is an anti-pattern unless the constructed object
has some intensive construction steps. -
10. Re: Generalizing dependency injection
wolfc Mar 13, 2008 12:01 PM (in response to starksm64)Pooling is not part of the mix right here. It's the next level.
What I showed is the interface with which EJB 3 pooling delegates for component creation. The factory needs to be injected into a pool.
There are both patterns and anti-patterns to pooling. What I showed at JBW was a resource-starvation scenario which makes EJB 3 (/ pooling) behave better than MC (/ instance). The question is whether to incorporate something like that in MC, but that's not what this thread is about. :-)
So pooling (which is outside of scope) will delegate to a component factory which will delegate to injection. So the pool is a higher level assembly. -
11. Re: Generalizing dependency injection
adrian.brock Mar 13, 2008 12:11 PM (in response to starksm64)"wolfc" wrote:
There are both patterns and anti-patterns to pooling. What I showed at JBW was a resource-starvation scenario which makes EJB 3 (/ pooling) behave better than MC (/ instance). The question is whether to incorporate something like that in MC, but that's not what this thread is about. :-)
OK then OFF-TOPIC
Pooling has nothing to do with what you are talking about. Using a factory
to create a new instance of stateless object without pooling
rather than using a singleton also has the nice behaviour of not causing contention
and not having to worry about thread safety etc.
ON-TOPIC
I agree, the factory should just be used to create objects for any pooling
implementation ejb3 or the user cares to implement (including none :-). -
12. Re: Generalizing dependency injection
wolfc Mar 13, 2008 12:41 PM (in response to starksm64)OFF-TOPIC :-)
Suppose I have a data source pool of 100 and I have two session beans which make use of that data source. One performs the search function for end users, the other is the admin interface.
Now I don't want to starve the data source by having 100 searchers active (and more in queue) while the admin is waiting to get anything done. So search bean will be pool limited to 75 and admin will receive similar treatment.
I say EJB 3 is all about resource management. :-) -
13. Re: Generalizing dependency injection
adrian.brock Mar 13, 2008 12:52 PM (in response to starksm64)"wolfc" wrote:
OFF-TOPIC :-)
Suppose I have a data source pool of 100 and I have two session beans which make use of that data source. One performs the search function for end users, the other is the admin interface.
Now I don't want to starve the data source by having 100 searchers active (and more in queue) while the admin is waiting to get anything done. So search bean will be pool limited to 75 and admin will receive similar treatment.
I say EJB 3 is all about resource management. :-)
What you are describing is called "flow control". You can do it outside an EJB
with an aspect, e.g. a semaphore controlling access to a singleton.
If the semaphore/pool uses priority queuing the admin request
can "jump the queue" based on a higher privilege. -
14. Re: Generalizing dependency injection
wolfc Mar 13, 2008 1:07 PM (in response to starksm64)"adrian@jboss.org" wrote:
What you are describing is called "flow control". You can do it outside an EJB
with an aspect, e.g. a semaphore controlling access to a singleton.
If the semaphore/pool uses priority queuing the admin request
can "jump the queue" based on a higher privilege.
A pool beats a semaphored singleton anytime.