-
1. Re: New feature proposal: byType injection of Spring beans
alesj Sep 27, 2006 1:35 PM (in response to c.vidal)Yep - an interesting feature.
Working on the same thing on Microcontainer. :-)
There are some issues with Spring 2.0 compatibility - so I hope I'll find some time to implement this stuff.
But it will definitely be a part of new JBoss deployers. -
2. Re: New feature proposal: byType injection of Spring beans
c.vidal Sep 28, 2006 3:45 AM (in response to c.vidal)Great, glad to hear that :D
-
3. Re: New feature proposal: byType injection of Spring beans
c.vidal Sep 28, 2006 10:10 AM (in response to c.vidal)Hi Ales,
Here is a quick and dirty patch. I just couldn't wait :) I didn't have the time to figure out how the jboss unit tests work though, so I didn't add any unit tests. If you could just explain that to me quickly, I'd be glad to add them.
The code tries to do as much guess-work as possible and i'm not sure if it's the best way to do it. The algorithm used is explained in the code.
Tell me if it suits you.
Regards,
CédricIndex: spring-int/src/main/org/jboss/spring/support/SpringInjectionSupport.java =================================================================== --- spring-int/src/main/org/jboss/spring/support/SpringInjectionSupport.java (revision 57255) +++ spring-int/src/main/org/jboss/spring/support/SpringInjectionSupport.java (working copy) @@ -26,6 +26,7 @@ import org.jboss.logging.Logger; import org.jboss.naming.Util; import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.util.Assert; import java.lang.reflect.Field; @@ -111,30 +112,101 @@ return m.getName().startsWith("set") && m.getParameterTypes().length == 1; } - private Object getObjectFromBeanFactory(Spring spring) throws Exception + private Object getObjectFromBeanFactory(Spring spring, String defaultBeanName, Class type) throws Exception { BeanFactory beanFactory = (BeanFactory) Util.lookup(spring.jndiName(), BeanFactory.class); - return beanFactory.getBean(spring.bean()); + return getObjectFromBeanFactory(spring, beanFactory, defaultBeanName, type); } + private Object getObjectFromBeanFactory(Spring spring, BeanFactory beanFactory, String defaultBeanName, Class type) { + Object bean = null; + + if(spring.bean() != null && spring.bean().length() > 0) { + + /* + * If the bean name is specified in the annotation, then the bean + * must looked up by name whether the bean factory is listable or + * not. + */ + bean = beanFactory.getBean(spring.bean()); + + } else { + if (beanFactory instanceof ListableBeanFactory) { + + /* + * If no bean name is specified in the annotation but the bean + * factory is listable then the bean is looked up by type. + */ + ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory; + Map beans = listableBeanFactory.getBeansOfType(type); + + if(beans.size() > 1) { + + /* + * If there is a ambiguity, try with the default name + */ + bean = beans.get(defaultBeanName); + + /* + * If no beans amongst the ones of the expected type has the + * default name then we can't do anything. + */ + if(bean == null) { + throw new IllegalArgumentException("More than one bean is of type " + type); + } + + } else { + Iterator beansIterator = beans.values().iterator(); + if(beansIterator.hasNext()) { + bean = beansIterator.next(); + } + } + + } else { + + /* + * If no bean name is specified in the annotation and the bean + * factory is not listable then the bean can only be looked up + * by its default name. + */ + bean = beanFactory.getBean(defaultBeanName); + + } + } + return bean; + } + private void injectToMethod(Object target, Method method, Spring spring) throws Exception { - Object bean = getObjectFromBeanFactory(spring); + String defaultBeanName = getDefaultBeanName(method); + Object bean = getObjectFromBeanFactory(spring, defaultBeanName, method.getReturnType()); doAssert(bean, method.getParameterTypes()[0]); logInjection(spring, bean, target, method); method.setAccessible(true); method.invoke(target, bean); } - private void injectToField(Object target, Field field, Spring spring) throws Exception + private void injectToField(Object target, Field field, Spring spring) throws Exception { - Object bean = getObjectFromBeanFactory(spring); + String defaultBeanName = getDefaultBeanName(field); + Object bean = getObjectFromBeanFactory(spring, defaultBeanName, field.getType()); doAssert(bean, field.getType()); logInjection(spring, bean, target, field); field.setAccessible(true); field.set(target, bean); } + private String getDefaultBeanName(Method method) { + String name = method.getName().substring(3, 3).toLowerCase(); + name += method.getName().substring(4); + return name; + } + + private String getDefaultBeanName(Field field) { + String name = field.getName(); + return name; + } + private void doAssert(Object bean, Class expectedBeanClass) { Assert.isTrue(expectedBeanClass.isAssignableFrom(bean.getClass()), Index: spring-int/src/main/org/jboss/annotation/spring/Spring.java =================================================================== --- spring-int/src/main/org/jboss/annotation/spring/Spring.java (revision 57255) +++ spring-int/src/main/org/jboss/annotation/spring/Spring.java (working copy) @@ -38,6 +38,6 @@ String jndiName(); - String bean(); + String bean() default ""; }
-
4. Re: New feature proposal: byType injection of Spring beans
c.vidal Sep 28, 2006 10:11 AM (in response to c.vidal)Btw, the patch was made against trunk, relative to the jboss root directory.
-
5. Re: New feature proposal: byType injection of Spring beans
alesj Oct 18, 2006 10:32 AM (in response to c.vidal)SpringDeployer compatible with Spring2.0 final.
http://www.jboss.org/index.html?module=bb&op=viewtopic&p=3979096