1 22 23 package org.jboss.spring.support; 24 25 import java.lang.reflect.Field ; 26 import java.lang.reflect.Member ; 27 import java.lang.reflect.Method ; 28 import java.util.*; 29 30 import org.jboss.annotation.spring.Spring; 31 import org.jboss.logging.Logger; 32 import org.jboss.util.naming.Util; 33 import org.springframework.beans.factory.BeanFactory; 34 import org.springframework.beans.factory.ListableBeanFactory; 35 36 45 public abstract class SpringInjectionSupport 46 { 47 48 protected Logger log = Logger.getLogger(getClass()); 49 private final Comparator<Method > METHOD_COMPARATOR = new MethodComparator(); 50 51 protected Object inject(Object target) throws Exception 52 { 53 54 log.debug("Invoking Spring injection: " + target.getClass().getName()); 55 56 Method [] methods = getAllMethods(target); 57 for (Method m : methods) 58 { 59 Spring spring = m.getAnnotation(Spring.class); 60 if (spring != null) 61 { 62 if (isSetterMethod(m)) 63 { 64 injectToMethod(target, m, spring); 65 } 66 else 67 { 68 log.warn("Spring annotation only allowed on setter methods."); 69 } 70 } 71 } 72 73 Field [] fields = getAllFields(target); 74 for (Field f : fields) 75 { 76 Spring spring = f.getAnnotation(Spring.class); 77 if (spring != null) 78 { 79 injectToField(target, f, spring); 80 } 81 } 82 83 return target; 84 } 85 86 protected Method [] getAllMethods(Object bean) 87 { 88 Class beanClass = bean.getClass(); 89 Set<Method > methods = new TreeSet<Method >(METHOD_COMPARATOR); 90 while (beanClass != Object .class) 91 { 92 methods.addAll(Arrays.asList(beanClass.getDeclaredMethods())); 93 beanClass = beanClass.getSuperclass(); 94 } 95 return methods.toArray(new Method [methods.size()]); 96 } 97 98 protected Field [] getAllFields(Object bean) 99 { 100 Class beanClass = bean.getClass(); 101 List<Field > fields = new ArrayList<Field >(); 102 while (beanClass != Object .class) 103 { 104 fields.addAll(Arrays.asList(beanClass.getDeclaredFields())); 105 beanClass = beanClass.getSuperclass(); 106 } 107 return fields.toArray(new Field [fields.size()]); 108 } 109 110 private boolean isSetterMethod(Method m) 111 { 112 return m.getName().startsWith("set") && m.getParameterTypes().length == 1; 113 } 114 115 private Object getObjectFromBeanFactory(Spring spring, String defaultBeanName, Class beanType) throws Exception 116 { 117 BeanFactory beanFactory = (BeanFactory) Util.lookup(spring.jndiName(), BeanFactory.class); 118 String beanName = spring.bean(); 119 if (beanName != null && beanName.length() > 0) 120 { 121 return beanFactory.getBean(beanName, beanType); 122 } 123 else 124 { 125 if (beanFactory instanceof ListableBeanFactory) 127 { 128 ListableBeanFactory lbf = (ListableBeanFactory) beanFactory; 129 Map beans = lbf.getBeansOfType(beanType); 130 if (beans.size() > 1) 131 { 132 Object bean = beans.get(defaultBeanName); 133 if (bean == null) 134 { 135 throw new IllegalArgumentException ("More than one bean of type: " + beanType); 136 } 137 return bean; 138 } 139 else if (beans.size() == 1) 140 { 141 return beans.values().iterator().next(); 142 } 143 else 144 { 145 throw new IllegalArgumentException ("No such bean by type: " + beanType); 146 } 147 } 148 else 149 { 150 return beanFactory.getBean(defaultBeanName, beanType); 152 } 153 } 154 } 155 156 private void injectToMethod(Object target, Method method, Spring spring) throws Exception 157 { 158 String defaultBeanName = getDefaultBeanName(method); 159 Object bean = getObjectFromBeanFactory(spring, defaultBeanName, method.getParameterTypes()[0]); 160 logInjection(spring, bean, target, method); 161 method.setAccessible(true); 162 method.invoke(target, bean); 163 } 164 165 protected String getDefaultBeanName(Method method) 166 { 167 StringBuffer buffer = new StringBuffer (); 168 buffer.append(method.getName().substring(3, 3).toLowerCase()); 169 buffer.append(method.getName().substring(4)); 170 return buffer.toString(); 171 } 172 173 private void injectToField(Object target, Field field, Spring spring) throws Exception 174 { 175 String defaultBeanName = getDefaultBeanName(field); 176 Object bean = getObjectFromBeanFactory(spring, defaultBeanName, field.getType()); 177 logInjection(spring, bean, target, field); 178 field.setAccessible(true); 179 field.set(target, bean); 180 } 181 182 protected String getDefaultBeanName(Field field) 183 { 184 return field.getName(); 185 } 186 187 private void logInjection(Spring spring, Object bean, Object target, Member m) 188 { 189 log.debug("Injecting bean '" + spring.bean() + "' of class type " + 190 bean.getClass().getName() + " into " + target + " via " + m); 191 } 192 193 197 private class MethodComparator implements Comparator<Method > 198 { 199 200 public int compare(Method m1, Method m2) 201 { 202 String name1 = m1.getName(); 203 String name2 = m2.getName(); 204 205 if (name1.equals(name2)) 206 { 207 Class returnType1 = m1.getReturnType(); 208 Class returnType2 = m2.getReturnType(); 209 Class [] params1 = m1.getParameterTypes(); 210 Class [] params2 = m1.getParameterTypes(); 211 if (params1.length == params2.length) 212 { 213 if (returnType1.equals(returnType2)) 214 { 215 int i; 216 int length = params1.length; 217 for (i = 0; i < length; i++) 218 { 219 if (!params1[i].equals(params2[i])) 220 { 221 break; 222 } 223 } 224 if (i < length) 226 { 227 return params1[i].getName().compareTo(params2[i].getName()); 228 } 229 else 230 { 231 if (m1.getAnnotation(Spring.class) != null) 233 { 234 log.warn("Found overridden @Spring annotated method: " + m1); 235 } 236 return 0; 237 } 238 } 239 else 240 { 241 return returnType1.getName().compareTo(returnType2.getName()); 242 } 243 } 244 else 245 { 246 return params1.length - params2.length; 247 } 248 } 249 else 250 { 251 return name1.compareTo(name2); 252 } 253 } 254 255 } 256 } 257 | Popular Tags |