package org.dayatang.domain.internal.bean; import org.dayatang.domain.InstanceLocator; import org.dayatang.domain.IocInstanceNotUniqueException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.inject.Named; import java.lang.annotation.Annotation; import java.util.HashSet; import java.util.ServiceLoader; import java.util.Set; /** * Created by yyang on 15/1/14. */ public class ServiceLoaderInstanceLocator implements InstanceLocator { private static final Logger LOGGER = LoggerFactory.getLogger(ServiceLoaderInstanceLocator.class); @Override public <T> T getInstance(Class<T> beanType) { Set<T> results = new HashSet<T>(); for (T instance : ServiceLoader.load(beanType)) { results.add(instance); } if (results.size() > 1) { throw new IocInstanceNotUniqueException("There're more than one bean of type '" + beanType + "'"); } if (results.size() == 1) { return results.iterator().next(); } LOGGER.warn("ServiceLoader cannot found bean of type {}", beanType); return null; } @Override public <T> T getInstance(Class<T> beanType, String beanName) { Set<T> results = new HashSet<T>(); for (T instance : ServiceLoader.load(beanType)) { Named named = instance.getClass().getAnnotation(Named.class); if (named != null && beanName.equals(named.value())) { results.add(instance); } } if (results.size() > 1) { throw new IocInstanceNotUniqueException("There're more than one bean of type '" + beanType + "' and named '" + beanName + "'"); } if (results.size() == 1) { return results.iterator().next(); } LOGGER.warn("ServiceLoader cannot found bean '{}' of type {}", beanName, beanType); return null; } @Override public <T> T getInstance(Class<T> beanType, Class<? extends Annotation> annotationType) { Set<T> results = new HashSet<T>(); for (T instance : ServiceLoader.load(beanType)) { Annotation beanAnnotation = instance.getClass().getAnnotation(annotationType); if (beanAnnotation != null && beanAnnotation.annotationType().equals(annotationType)) { results.add(instance); } } if (results.size() > 1) { throw new IocInstanceNotUniqueException("There're more than one bean of type '" + beanType + "' and annotated with '" + annotationType + "'"); } if (results.size() == 1) { return results.iterator().next(); } LOGGER.warn("ServiceLoader cannot found bean of type {} with annotation {}", beanType, annotationType); return null; } }