Search in sources :

Example 1 with IocException

use of org.nutz.ioc.IocException in project nutz by nutzam.

the class DefaultValueProxyMaker method make.

@SuppressWarnings("unchecked")
public ValueProxy make(IocMaking ing, IocValue iv) {
    Object value = iv.getValue();
    String type = iv.getType();
    // Null
    if ("null".equals(type) || null == value) {
        return new StaticValue(null);
    }
    if (value instanceof ValueProxy) {
        return (ValueProxy) value;
    } else // String, Number, .....
    if ("normal".equals(type) || null == type) {
        // Array
        if (value.getClass().isArray()) {
            Object[] vs = (Object[]) value;
            IocValue[] tmp = new IocValue[vs.length];
            for (int i = 0; i < tmp.length; i++) tmp[i] = (IocValue) vs[i];
            return new ArrayValue(ing, tmp);
        } else // Map
        if (value instanceof Map<?, ?>) {
            return new MapValue(ing, (Map<String, IocValue>) value, (Class<? extends Map<String, Object>>) value.getClass());
        } else // Collection
        if (value instanceof Collection<?>) {
            return new CollectionValue(ing, (Collection<IocValue>) value, (Class<? extends Collection<Object>>) value.getClass());
        } else // Inner Object
        if (value instanceof IocObject) {
            return new InnerValue((IocObject) value);
        }
        return new StaticValue(value);
    } else // Refer
    if ("refer".equals(type)) {
        String s = value.toString();
        if (null != s) {
            String renm = s.toLowerCase();
            // $Ioc
            if ("$ioc".equals(renm)) {
                return new IocSelfValue();
            } else // $Name
            if ("$name".equals(renm)) {
                return new ObjectNameValue();
            } else // $Context
            if ("$context".equals(renm)) {
                return new IocContextObjectValue();
            }
        }
        return new ReferValue(s);
    } else // Refer_Type
    if (IocValue.TYPE_REFER_TYPE.equals(type)) {
        if (value instanceof CharSequence) {
            String[] tmp = value.toString().split("#");
            return new ReferTypeValue(tmp[0], Lang.forName(tmp[1], Object.class));
        } else if (value instanceof Field) {
            return new ReferTypeValue((Field) value);
        }
        throw new IocException(ing.getObjectName(), "unspported refer_type:'%s'", value);
    } else // Java
    if ("java".equals(type)) {
        return new JavaValue(value.toString());
    } else // File
    if ("file".equals(type)) {
        return new FileValue(value.toString());
    } else // Env
    if ("env".equals(type)) {
        return new EnvValue(value);
    } else // System Properties
    if ("sys".equals(type)) {
        return new SysPropValue(value);
    } else // Inner
    if ("inner".equals(type)) {
        return new InnerValue((IocObject) value);
    } else // JNDI
    if ("jndi".equals(type)) {
        return new JNDI_Value(value.toString());
    } else if ("el".equals(type)) {
        return new EL_Value(value.toString());
    }
    return null;
}
Also used : IocException(org.nutz.ioc.IocException) Field(java.lang.reflect.Field) ValueProxy(org.nutz.ioc.ValueProxy) IocObject(org.nutz.ioc.meta.IocObject) IocValue(org.nutz.ioc.meta.IocValue) Collection(java.util.Collection) IocObject(org.nutz.ioc.meta.IocObject) Map(java.util.Map)

Example 2 with IocException

use of org.nutz.ioc.IocException in project nutz by nutzam.

the class NutIoc method get.

public <T> T get(Class<T> type, String name, IocContext context) throws IocException {
    if (log.isDebugEnabled())
        log.debugf("Get '%s'<%s>", name, type == null ? "" : type);
    try {
        if (this.mirrors instanceof LifeCycle)
            ((LifeCycle) this.mirrors).init();
    } catch (Exception e) {
        throw new IocException("_mirror_factory_init", e, "Mirror Factory init fail");
    }
    // 创建对象创建时
    IocMaking ing = makeIocMaking(context, name);
    IocContext cntx = ing.getContext();
    // 从上下文缓存中获取对象代理
    ObjectProxy op = cntx.fetch(name);
    // 如果未发现对象
    if (null == op) {
        // 线程同步
        synchronized (lock_get) {
            // 再次读取
            op = cntx.fetch(name);
            // 如果未发现对象
            if (null == op) {
                try {
                    if (log.isDebugEnabled())
                        log.debug("\t >> Load definition name=" + name);
                    // 读取对象定义
                    IocObject iobj = loader.load(createLoading(), name);
                    if (null == iobj) {
                        for (String iocBeanName : loader.getName()) {
                            // 感觉没必要..没有就没有呗
                            if (3 > LevenshteinDistance.computeLevenshteinDistance(name.toLowerCase(), iocBeanName.toLowerCase())) {
                                throw new IocException(name, "Undefined object '%s' but found similar name '%s'", name, iocBeanName);
                            }
                        }
                        throw new IocException(name, "Undefined object '%s'", name);
                    }
                    // 修正对象类型
                    if (null == iobj.getType())
                        if (null == type && Strings.isBlank(iobj.getFactory()))
                            throw new IocException(name, "NULL TYPE object '%s'", name);
                        else
                            iobj.setType(type);
                    // 检查对象级别
                    if (Strings.isBlank(iobj.getScope()))
                        iobj.setScope(defaultScope);
                    // 根据对象定义,创建对象,maker 会自动的缓存对象到 context 中
                    if (log.isDebugEnabled())
                        log.debugf("\t >> Make...'%s'<%s>", name, type == null ? "" : type);
                    op = maker.make(ing, iobj);
                }// 处理异常
                 catch (IocException e) {
                    ((IocException) e).addBeanNames(name);
                    throw e;
                } catch (Throwable e) {
                    throw new IocException(name, e, "For object [%s] - type:[%s]", name, type == null ? "" : type);
                }
            }
        }
    }
    synchronized (lock_get) {
        T re = op.get(type, ing);
        if (!name.startsWith("$") && re instanceof IocLoader) {
            loader.addLoader((IocLoader) re);
        }
        return re;
    }
}
Also used : LifeCycle(org.nutz.lang.util.LifeCycle) IocContext(org.nutz.ioc.IocContext) IocMaking(org.nutz.ioc.IocMaking) IocException(org.nutz.ioc.IocException) IocObject(org.nutz.ioc.meta.IocObject) ComboIocLoader(org.nutz.ioc.loader.combo.ComboIocLoader) IocLoader(org.nutz.ioc.IocLoader) ObjectProxy(org.nutz.ioc.ObjectProxy) IocException(org.nutz.ioc.IocException)

Example 3 with IocException

use of org.nutz.ioc.IocException in project nutz by nutzam.

the class ObjectMakerImpl method make.

public ObjectProxy make(final IocMaking ing, IocObject iobj) {
    // 获取 Mirror, AOP 将在这个方法中进行
    Mirror<?> mirror = ing.getMirrors().getMirror(iobj.getType(), ing.getObjectName());
    // 获取配置的对象事件集合
    IocEventSet iocEventSet = iobj.getEvents();
    // 建立对象代理,并保存在上下文环境中 只有对象为 singleton
    // 并且有一个非 null 的名称的时候才会保存
    // 就是说,所有内部对象,将会随这其所附属的对象来保存,而自己不会单独保存
    ObjectProxy op = new ObjectProxy();
    if (iobj.isSingleton() && null != ing.getObjectName())
        ing.getContext().save(iobj.getScope(), ing.getObjectName(), op);
    // 为对象代理设置触发事件
    if (null != iobj.getEvents()) {
        op.setFetch(createTrigger(mirror, iocEventSet.getFetch()));
        op.setDepose(createTrigger(mirror, iocEventSet.getDepose()));
    }
    try {
        // 准备对象的编织方式
        DefaultWeaver dw = new DefaultWeaver();
        op.setWeaver(dw);
        // 为编织器设置事件触发器:创建时
        if (null != iobj.getEvents()) {
            dw.setCreate(createTrigger(mirror, iocEventSet.getCreate()));
        }
        // 构造函数参数
        ValueProxy[] vps = new ValueProxy[Lang.length(iobj.getArgs())];
        for (int i = 0; i < vps.length; i++) vps[i] = ing.makeValue(iobj.getArgs()[i]);
        dw.setArgs(vps);
        // 先获取一遍,根据这个数组来获得构造函数
        Object[] args = new Object[vps.length];
        boolean hasNullArg = false;
        for (int i = 0; i < args.length; i++) {
            args[i] = vps[i].get(ing);
            if (args[i] == null) {
                hasNullArg = true;
            }
        }
        // 缓存构造函数
        if (iobj.getFactory() != null) {
            // factory这属性, 格式应该是 类名#方法名 或者 $iocbean#方法名
            final String[] ss = iobj.getFactory().split("#", 2);
            if (ss[0].startsWith("$")) {
                dw.setBorning(new Borning<Object>() {

                    public Object born(Object... args) {
                        Object factoryBean = ing.getIoc().get(null, ss[0].substring(1));
                        return Mirror.me(factoryBean).invoke(factoryBean, ss[1], args);
                    }
                });
            } else {
                Mirror<?> mi = Mirror.me(Lang.loadClass(ss[0]));
                if (hasNullArg) {
                    Method m = (Method) Lang.first(mi.findMethods(ss[1], args.length));
                    if (m == null)
                        throw new IocException(ing.getObjectName(), "Factory method not found --> ", iobj.getFactory());
                    dw.setBorning(new MethodCastingBorning<Object>(m));
                } else {
                    Method m = mi.findMethod(ss[1], args);
                    dw.setBorning(new MethodBorning<Object>(m));
                }
            }
        } else {
            dw.setBorning((Borning<?>) mirror.getBorning(args));
        }
        // 如果这个对象是容器中的单例,那么就可以生成实例了
        // 这一步非常重要,它解除了字段互相引用的问题
        Object obj = null;
        if (iobj.isSingleton()) {
            obj = dw.born(ing);
            op.setObj(obj);
        }
        // 获得每个字段的注入方式
        List<IocField> _fields = new ArrayList<IocField>(iobj.getFields().values());
        FieldInjector[] fields = new FieldInjector[_fields.size()];
        for (int i = 0; i < fields.length; i++) {
            IocField ifld = _fields.get(i);
            try {
                ValueProxy vp = ing.makeValue(ifld.getValue());
                fields[i] = FieldInjector.create(mirror, ifld.getName(), vp, ifld.isOptional());
            } catch (Exception e) {
                throw Lang.wrapThrow(e, "Fail to eval Injector for field: '%s'", ifld.getName());
            }
        }
        dw.setFields(fields);
        // 如果是单例对象,前面已经生成实例了,在这里需要填充一下它的字段
        if (null != obj)
            dw.fill(ing, obj);
        // 对象创建完毕,如果有 create 事件,调用它
        dw.onCreate(obj);
    } catch (IocException e) {
        ing.getContext().remove(iobj.getScope(), ing.getObjectName());
        ((IocException) e).addBeanNames(ing.getObjectName());
        throw e;
    }// 当异常发生,从 context 里移除 ObjectProxy
     catch (Throwable e) {
        ing.getContext().remove(iobj.getScope(), ing.getObjectName());
        throw new IocException(ing.getObjectName(), e, "throw Exception when creating");
    }
    // 返回
    return op;
}
Also used : IocException(org.nutz.ioc.IocException) ArrayList(java.util.ArrayList) Method(java.lang.reflect.Method) FieldInjector(org.nutz.ioc.weaver.FieldInjector) IocException(org.nutz.ioc.IocException) DefaultWeaver(org.nutz.ioc.weaver.DefaultWeaver) ValueProxy(org.nutz.ioc.ValueProxy) IocEventSet(org.nutz.ioc.meta.IocEventSet) IocField(org.nutz.ioc.meta.IocField) ObjectProxy(org.nutz.ioc.ObjectProxy) IocObject(org.nutz.ioc.meta.IocObject)

Example 4 with IocException

use of org.nutz.ioc.IocException in project nutz by nutzam.

the class AnnotationIocLoader method addClass.

protected void addClass(Class<?> classZ) {
    if (classZ.isInterface() || classZ.isMemberClass() || classZ.isEnum() || classZ.isAnnotation() || classZ.isAnonymousClass())
        return;
    int modify = classZ.getModifiers();
    if (Modifier.isAbstract(modify) || (!Modifier.isPublic(modify)))
        return;
    IocBean iocBean = classZ.getAnnotation(IocBean.class);
    if (iocBean != null) {
        if (log.isDebugEnabled())
            log.debugf("Found @IocBean : %s", classZ);
        // 采用 @IocBean->name
        String beanName = iocBean.name();
        if (Strings.isBlank(beanName)) {
            // 否则采用 @InjectName
            InjectName innm = classZ.getAnnotation(InjectName.class);
            if (null != innm && !Strings.isBlank(innm.value())) {
                beanName = innm.value();
            } else // 大哥(姐),您都不设啊!? 那就用 simpleName 吧
            {
                beanName = Strings.lowerFirst(classZ.getSimpleName());
            }
        }
        // 重名了, 需要用户用@IocBean(name="xxxx") 区分一下
        if (map.containsKey(beanName))
            throw new IocException(beanName, "Duplicate beanName=%s, by %s !!  Have been define by %s !!", beanName, classZ.getName(), map.get(beanName).getType().getName());
        IocObject iocObject = new IocObject();
        iocObject.setType(classZ);
        map.put(beanName, iocObject);
        iocObject.setSingleton(iocBean.singleton());
        if (!Strings.isBlank(iocBean.scope()))
            iocObject.setScope(iocBean.scope());
        // 看看构造函数都需要什么函数
        String[] args = iocBean.args();
        // args = iocBean.param();
        if (null != args && args.length > 0)
            for (String value : args) iocObject.addArg(Iocs.convert(value, true));
        // 设置Events
        IocEventSet eventSet = new IocEventSet();
        iocObject.setEvents(eventSet);
        if (!Strings.isBlank(iocBean.create()))
            eventSet.setCreate(iocBean.create().trim().intern());
        if (!Strings.isBlank(iocBean.depose()))
            eventSet.setDepose(iocBean.depose().trim().intern());
        if (!Strings.isBlank(iocBean.fetch()))
            eventSet.setFetch(iocBean.fetch().trim().intern());
        // 处理字段(以@Inject方式,位于字段)
        List<String> fieldList = new ArrayList<String>();
        Mirror<?> mirror = Mirror.me(classZ);
        Field[] fields = mirror.getFields(Inject.class);
        for (Field field : fields) {
            Inject inject = field.getAnnotation(Inject.class);
            // 无需检查,因为字段名是唯一的
            // if(fieldList.contains(field.getName()))
            // throw duplicateField(classZ,field.getName());
            IocField iocField = new IocField();
            iocField.setName(field.getName());
            IocValue iocValue;
            if (Strings.isBlank(inject.value())) {
                iocValue = new IocValue();
                iocValue.setType(IocValue.TYPE_REFER_TYPE);
                iocValue.setValue(field);
            } else
                iocValue = Iocs.convert(inject.value(), true);
            iocField.setValue(iocValue);
            iocField.setOptional(inject.optional());
            iocObject.addField(iocField);
            fieldList.add(iocField.getName());
        }
        // 处理字段(以@Inject方式,位于set方法)
        Method[] methods;
        try {
            methods = classZ.getMethods();
        } catch (Exception e) {
            // 如果获取失败,就忽略之
            log.infof("Fail to call getMethods() in Class=%s, miss class or Security Limit, ignore it", classZ, e);
            methods = new Method[0];
        } catch (NoClassDefFoundError e) {
            log.infof("Fail to call getMethods() in Class=%s, miss class or Security Limit, ignore it", classZ, e);
            methods = new Method[0];
        }
        for (Method method : methods) {
            Inject inject = method.getAnnotation(Inject.class);
            if (inject == null)
                continue;
            // 过滤特殊方法
            int m = method.getModifiers();
            if (Modifier.isAbstract(m) || (!Modifier.isPublic(m)) || Modifier.isStatic(m))
                continue;
            String methodName = method.getName();
            if (methodName.startsWith("set") && methodName.length() > 3 && method.getParameterTypes().length == 1) {
                IocField iocField = new IocField();
                iocField.setName(Strings.lowerFirst(methodName.substring(3)));
                if (fieldList.contains(iocField.getName()))
                    throw duplicateField(beanName, classZ, iocField.getName());
                IocValue iocValue;
                if (Strings.isBlank(inject.value())) {
                    iocValue = new IocValue();
                    iocValue.setType(IocValue.TYPE_REFER_TYPE);
                    iocValue.setValue(Strings.lowerFirst(methodName.substring(3)) + "#" + method.getParameterTypes()[0].getName());
                } else
                    iocValue = Iocs.convert(inject.value(), true);
                iocField.setValue(iocValue);
                iocObject.addField(iocField);
                fieldList.add(iocField.getName());
            }
        }
        // 处理字段(以@IocBean.field方式)
        String[] flds = iocBean.fields();
        if (flds != null && flds.length > 0) {
            for (String fieldInfo : flds) {
                if (fieldList.contains(fieldInfo))
                    throw duplicateField(beanName, classZ, fieldInfo);
                IocField iocField = new IocField();
                if (fieldInfo.contains(":")) {
                    // dao:jndi:dataSource/jdbc形式
                    String[] datas = fieldInfo.split(":", 2);
                    // 完整形式, 与@Inject完全一致了
                    iocField.setName(datas[0]);
                    iocField.setValue(Iocs.convert(datas[1], true));
                    iocObject.addField(iocField);
                } else {
                    // 基本形式, 引用与自身同名的bean
                    iocField.setName(fieldInfo);
                    IocValue iocValue = new IocValue();
                    iocValue.setType(IocValue.TYPE_REFER);
                    iocValue.setValue(fieldInfo);
                    iocField.setValue(iocValue);
                    iocObject.addField(iocField);
                }
                fieldList.add(iocField.getName());
            }
        }
        // 处理工厂方法
        if (!Strings.isBlank(iocBean.factory())) {
            iocObject.setFactory(iocBean.factory());
        }
    } else {
    // 不再检查其他类.
    }
}
Also used : IocException(org.nutz.ioc.IocException) IocObject(org.nutz.ioc.meta.IocObject) ArrayList(java.util.ArrayList) Method(java.lang.reflect.Method) ObjectLoadException(org.nutz.ioc.ObjectLoadException) IocException(org.nutz.ioc.IocException) Field(java.lang.reflect.Field) IocField(org.nutz.ioc.meta.IocField) IocEventSet(org.nutz.ioc.meta.IocEventSet) IocValue(org.nutz.ioc.meta.IocValue) IocField(org.nutz.ioc.meta.IocField) InjectName(org.nutz.ioc.annotation.InjectName)

Example 5 with IocException

use of org.nutz.ioc.IocException in project nutz by nutzam.

the class NutIoc method getByType.

public <K> K getByType(Class<K> klass, IocContext context) {
    String _name = null;
    IocContext cntx;
    if (null == context || context == this.context)
        cntx = this.context;
    else
        cntx = new ComboContext(context, this.context);
    for (String name : cntx.names()) {
        ObjectProxy op = cntx.fetch(name);
        if (op.getObj() != null && klass.isAssignableFrom(op.getObj().getClass())) {
            _name = name;
            break;
        }
    }
    if (_name != null)
        return get(klass, _name, context);
    for (String name : getNames()) {
        try {
            IocObject iobj = loader.load(createLoading(), name);
            if (iobj != null && iobj.getType() != null && klass.isAssignableFrom(iobj.getType()))
                _name = name;
        } catch (Exception e) {
            continue;
        }
        if (_name != null)
            return get(klass, name, context);
    }
    throw new IocException("class:" + klass.getName(), "none ioc bean match class=" + klass.getName());
}
Also used : IocContext(org.nutz.ioc.IocContext) IocObject(org.nutz.ioc.meta.IocObject) IocException(org.nutz.ioc.IocException) ObjectProxy(org.nutz.ioc.ObjectProxy) IocException(org.nutz.ioc.IocException)

Aggregations

IocException (org.nutz.ioc.IocException)5 IocObject (org.nutz.ioc.meta.IocObject)5 ObjectProxy (org.nutz.ioc.ObjectProxy)3 Field (java.lang.reflect.Field)2 Method (java.lang.reflect.Method)2 ArrayList (java.util.ArrayList)2 IocContext (org.nutz.ioc.IocContext)2 ValueProxy (org.nutz.ioc.ValueProxy)2 IocEventSet (org.nutz.ioc.meta.IocEventSet)2 IocField (org.nutz.ioc.meta.IocField)2 IocValue (org.nutz.ioc.meta.IocValue)2 Collection (java.util.Collection)1 Map (java.util.Map)1 IocLoader (org.nutz.ioc.IocLoader)1 IocMaking (org.nutz.ioc.IocMaking)1 ObjectLoadException (org.nutz.ioc.ObjectLoadException)1 InjectName (org.nutz.ioc.annotation.InjectName)1 ComboIocLoader (org.nutz.ioc.loader.combo.ComboIocLoader)1 DefaultWeaver (org.nutz.ioc.weaver.DefaultWeaver)1 FieldInjector (org.nutz.ioc.weaver.FieldInjector)1