package li.ioc; import java.lang.reflect.Type; import java.util.Arrays; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import li.model.Bean; import li.util.Reflect; import li.util.Strings; import li.util.Verify; /** * Ioc工具类,用于从IocContext中得到一个对象 * * @author li (limingwei@mail.com) * @version 0.1.3 (2012-05-08) */ public class Ioc { private static final Map<Object, Object> CACHE = new ConcurrentHashMap<Object, Object>(); /** * 若一个Bean为type类型或其子类型,则返回他的实例 */ public static <T> T get(Class<T> type) { Object target = CACHE.get(type); if (null == target) { for (Bean bean : IocContext.getInstance().getBeans()) { if (type.isAssignableFrom(bean.type)) { CACHE.put(type, bean.instance); return (T) bean.instance; } } } return (T) target; } /** * 若Bean名称直接匹配则返回 */ public static <T> T get(String name) { Object target = CACHE.get(name); if (null == target) { for (Bean bean : IocContext.getInstance().getBeans()) { if (!Verify.isEmpty(name) && bean.name.equals(name)) { CACHE.put(name, bean.instance); return (T) bean.instance; } } } return (T) target; } /** * 返回名称和类型均符合的Bean,若没有,则返回类型符合的一个Bean */ public static <T> T get(Class<T> type, String name) { String key = type + "#" + name; Object target = CACHE.get(key); if (null == target) { if (!Verify.isEmpty(name) && null != type) { for (Bean bean : IocContext.getInstance().getBeans()) { if (type.isAssignableFrom(bean.type) && bean.name.equals(name)) { CACHE.put(key, bean.instance); return (T) bean.instance; } } } } return null == target ? get(type) : (T) target;// 如果name为空则使用GetByType查找 } /** * 若类型匹配,且泛型参数的实际类型为genericType,则返回他的实例 * * @param genericTypes Bean泛型类型 */ public static <T> T get(Class<T> type, Type... genericTypes) { String key = Strings.link("#", genericTypes); Object target = CACHE.get(key); if (null == target) { for (Bean bean : IocContext.getInstance().getBeans()) { if (type.isAssignableFrom(bean.type) && null != genericTypes && Arrays.equals(genericTypes, Reflect.actualTypes(bean.type))) { CACHE.put(key, bean.instance); return (T) bean.instance; } } } return (T) target; } }