/** * @return all {@link Bean} annotated classes * <p>Includes all classes that implement an interface that has a {@link Bean} annotation */ public Set<Class> collect(IClassInventory classInventory) { Set<Class> allBeans = new HashSet<>(); // 1. collect all annotations annotated with @Bean and register all classes that are directly // annotated with @Bean Set<IClassInfo> beanAnnotations = new HashSet<>(); for (IClassInfo ci : classInventory.getKnownAnnotatedTypes(Bean.class)) { if (ci.isAnnotation()) { beanAnnotations.add(ci); } else { collectWithSubClasses(classInventory, ci, allBeans); } } // 2. register all classes that are somehow annotated with @Bean for (IClassInfo annotation : beanAnnotations) { try { for (IClassInfo ci : classInventory.getKnownAnnotatedTypes(annotation.resolveClass())) { collectWithSubClasses(classInventory, ci, allBeans); } } catch (Exception e) { LOG.warn("Could not resolve known annotated types for [{}]", annotation.name(), e); } } return allBeans; }
/** @param ci */ private void collectWithSubClasses( IClassInventory classInventory, IClassInfo ci, Set<Class> collector) { if (ci.isEnum() || ci.isAnnotation() || ci.isSynthetic() || !ci.isPublic()) { LOG.debug( "Skipping bean candidate '{}' because it is no supported class type (enum, annotation, anonymous class) or is not public.", ci.name()); return; } collect(ci, collector); if (!ci.isFinal()) { try { Set<IClassInfo> allKnownSubClasses = classInventory.getAllKnownSubClasses(ci.resolveClass()); for (IClassInfo subClass : allKnownSubClasses) { collect(subClass, collector); } } catch (Exception e) { LOG.warn("Could not resolve known sub classes of [{}]", ci.name(), e); } } }