/** * Looks up a bean reference based on type and qualifiers. Returns <tt>null</tt> if there is no * type associated with the specified * * @param type The type of the bean * @param qualifiers qualifiers to match * @param <T> The type of the bean * @return An instance of the {@link IOCSingletonBean} for the matching type and qualifiers. * Returns null if there is no matching type. Throws an {@link IOCResolutionException} if * there is a matching type but none of the qualifiers match or if more than one bean matches. */ @SuppressWarnings("unchecked") public <T> IOCBeanDef<T> lookupBean(Class<T> type, Annotation... qualifiers) { final List<IOCBeanDef> beanList = beanMap.get(type); if (beanList == null) { return null; } if (beanList.size() == 1) { return beanList.get(0); } final Set<Annotation> qualSet = new HashSet<Annotation>(qualifiers.length * 2); Collections.addAll(qualSet, qualifiers); final List<IOCBeanDef> matching = new ArrayList<IOCBeanDef>(); for (IOCBeanDef iocBean : beanList) { if (iocBean.matches(qualSet)) { matching.add(iocBean); } } if (matching.isEmpty()) { throw new IOCResolutionException("no matching bean instances for: " + type.getName()); } else if (matching.size() > 1) { throw new IOCResolutionException("multiple matching bean instances for: " + type.getName()); } else { return matching.get(0); } }
/** * Register a bean with the manager. * * @param bean an {@link IOCSingletonBean} reference */ public void registerBean(final IOCBeanDef bean) { List<IOCBeanDef> beans = beanMap.get(bean.getType()); if (beans == null) { beanMap.put(bean.getType(), beans = new ArrayList<IOCBeanDef>()); } beans.add(bean); }
@SuppressWarnings("unchecked") private void resolveAllProxies() { boolean beansResolved = false; final Iterator<Map.Entry<BeanRef, List<ProxyResolver>>> unresolvedIterator = new LinkedHashMap<BeanRef, List<ProxyResolver>>(unresolvedProxies).entrySet().iterator(); final int initialSize = unresolvedProxies.size(); while (unresolvedIterator.hasNext()) { final Map.Entry<BeanRef, List<ProxyResolver>> entry = unresolvedIterator.next(); if (wired.containsKey(entry.getKey())) { final Object wiredInst = wired.get(entry.getKey()); for (final ProxyResolver pr : entry.getValue()) { pr.resolve(wiredInst); } final Iterator<Tuple<Object, InitializationCallback>> initCallbacks = initializationCallbacks.iterator(); while (initCallbacks.hasNext()) { final Tuple<Object, InitializationCallback> tuple = initCallbacks.next(); if (tuple.getKey() == wiredInst) { tuple.getValue().init(tuple.getKey()); initCallbacks.remove(); } } unresolvedIterator.remove(); } else { final IOCBeanDef<?> iocBeanDef = IOC.getBeanManager() .lookupBean(entry.getKey().getClazz(), entry.getKey().getAnnotations()); if (iocBeanDef != null) { if (!wired.containsKey(entry.getKey())) { addBean( getBeanReference(entry.getKey().getClazz(), entry.getKey().getAnnotations()), iocBeanDef.getInstance(this)); } beansResolved = true; } } } if (beansResolved) { resolveAllProxies(); } else if (!unresolvedProxies.isEmpty() && initialSize != unresolvedProxies.size()) { throw new RuntimeException( "unresolved proxy: " + unresolvedProxies.entrySet().iterator().next().getKey()); } }
/** * Obtains an instance of the bean within the creational context based on the specified bean type * and qualifiers. * * @param beanType the type of the bean * @param qualifiers the qualifiers fo the bean * @param <T> the type of the bean * @return the actual instance of the bean */ @SuppressWarnings("unchecked") public <T> T getBeanInstance(final Class<T> beanType, final Annotation[] qualifiers) { final T t = (T) wired.get(getBeanReference(beanType, qualifiers)); if (t == null) { // see if the instance is available in the bean manager final Collection<IOCBeanDef<T>> beanList = IOC.getBeanManager().lookupBeans(beanType, qualifiers); if (!beanList.isEmpty()) { final IOCBeanDef<T> bean = beanList.iterator().next(); if (bean != null && bean instanceof IOCSingletonBean) { return bean.getInstance(); } } } return t; }