Search in sources :

Example 1 with IocField

use of org.nutz.ioc.meta.IocField in project nutz by nutzam.

the class XmlIocLoaderTest method testXmlIocLoader.

@Test
public void testXmlIocLoader() throws ObjectLoadException {
    IocLoader iocLoader = getNew("org/nutz/ioc/loader/xml/conf/zzh-offered.xml");
    assertTrue(iocLoader.getName() != null);
    assertTrue(iocLoader.getName().length > 0);
    for (String name : iocLoader.getName()) {
        assertNotNull(name);
        assertNotNull(iocLoader.load(null, name));
        IocObject iocObject = iocLoader.load(null, name);
        if (iocObject.hasArgs()) {
            for (IocValue iocValue : iocObject.getArgs()) {
                iocValue.getType();
                iocValue.getValue();
                checkValue(iocValue);
            }
        }
        if (iocObject.getFields() != null) {
            for (IocField iocField : iocObject.getFields().values()) {
                assertNotNull(iocField.getName());
                if (iocField.getValue() != null) {
                    IocValue iocValue = iocField.getValue();
                    checkValue(iocValue);
                }
            }
        }
    }
    iocLoader.load(null, "obj").getFields().values().iterator().next().getValue().getValue();
}
Also used : IocValue(org.nutz.ioc.meta.IocValue) IocObject(org.nutz.ioc.meta.IocObject) IocLoader(org.nutz.ioc.IocLoader) IocField(org.nutz.ioc.meta.IocField) Test(org.junit.Test)

Example 2 with IocField

use of org.nutz.ioc.meta.IocField in project nutz by nutzam.

the class IocLoading method map2iobj.

@SuppressWarnings("unchecked")
public IocObject map2iobj(Map<String, Object> map) throws ObjectLoadException {
    final IocObject iobj = new IocObject();
    if (!isIocObject(map)) {
        for (Entry<String, Object> en : map.entrySet()) {
            IocField ifld = new IocField();
            ifld.setName(en.getKey());
            ifld.setValue(object2value(en.getValue()));
            iobj.addField(ifld);
        }
    //            if (log.isWarnEnabled()) // TODO 移除这种兼容性
    //                log.warn("Using *Declared* ioc-define (without type or events)!!! Pls use Standard Ioc-Define!!"
    //                            + " Bean will define as:\n"
    //                            + Json.toJson(iobj));
    } else {
        Object v = map.get("type");
        // type
        try {
            String typeName = (String) v;
            if (!Strings.isBlank(typeName)) {
                iobj.setType(Lang.loadClass(typeName));
            }
        } catch (Exception e) {
            throw E(e, "Wrong type name: '%s'", v);
        }
        // singleton
        try {
            v = map.get("singleton");
            if (null != v)
                iobj.setSingleton(Castors.me().castTo(v, boolean.class));
        } catch (FailToCastObjectException e) {
            throw E(e, "Wrong singleton: '%s'", v);
        }
        // scope
        v = map.get("scope");
        if (null != v)
            iobj.setScope(v.toString());
        // events
        try {
            v = map.get("events");
            if (null != v) {
                IocEventSet ies = Lang.map2Object((Map<?, ?>) v, IocEventSet.class);
                iobj.setEvents(ies);
            }
        } catch (Exception e) {
            throw E(e, "Wrong events: '%s'", v);
        }
        // args
        try {
            v = map.get("args");
            if (null != v) {
                Lang.each(v, new Each<Object>() {

                    public void invoke(int i, Object ele, int length) {
                        iobj.addArg(object2value(ele));
                    }
                });
            }
        } catch (Exception e) {
            throw E(e, "Wrong args: '%s'", v);
        }
        // fields
        try {
            v = map.get("fields");
            if (null != v) {
                Map<String, Object> fields = (Map<String, Object>) v;
                for (Entry<String, Object> en : fields.entrySet()) {
                    IocField ifld = new IocField();
                    ifld.setName(en.getKey());
                    ifld.setValue(object2value(en.getValue()));
                    iobj.addField(ifld);
                }
            }
        } catch (Exception e) {
            throw E(e, "Wrong args: '%s'", v);
        }
        // factory方法
        v = map.get("factory");
        if (v != null && !Strings.isBlank(v.toString())) {
            iobj.setFactory(v.toString());
        }
    }
    return iobj;
}
Also used : IocEventSet(org.nutz.ioc.meta.IocEventSet) FailToCastObjectException(org.nutz.castor.FailToCastObjectException) IocObject(org.nutz.ioc.meta.IocObject) Iocs.isIocObject(org.nutz.ioc.Iocs.isIocObject) IocField(org.nutz.ioc.meta.IocField) IocObject(org.nutz.ioc.meta.IocObject) Iocs.isIocObject(org.nutz.ioc.Iocs.isIocObject) HashMap(java.util.HashMap) Map(java.util.Map) FailToCastObjectException(org.nutz.castor.FailToCastObjectException)

Example 3 with IocField

use of org.nutz.ioc.meta.IocField 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 IocField

use of org.nutz.ioc.meta.IocField 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 IocField

use of org.nutz.ioc.meta.IocField in project nutz by nutzam.

the class XmlIocLoader method parseFields.

protected void parseFields(Element beanElement, IocObject iocObject) throws Throwable {
    List<Element> list = getChildNodesByTagName(beanElement, TAG_FIELD);
    for (Element fieldElement : list) {
        IocField iocField = new IocField();
        iocField.setName(fieldElement.getAttribute("name"));
        if ("true".equals(fieldElement.getAttribute("optional")))
            iocField.setOptional(true);
        if (fieldElement.hasChildNodes()) {
            NodeList nodeList = fieldElement.getChildNodes();
            for (int j = 0; j < nodeList.getLength(); j++) {
                if (nodeList.item(j) instanceof Element) {
                    iocField.setValue(parseX((Element) nodeList.item(j)));
                    break;
                }
            }
        }
        iocObject.addField(iocField);
    }
}
Also used : Element(org.w3c.dom.Element) NodeList(org.w3c.dom.NodeList) IocField(org.nutz.ioc.meta.IocField)

Aggregations

IocField (org.nutz.ioc.meta.IocField)5 IocObject (org.nutz.ioc.meta.IocObject)4 IocEventSet (org.nutz.ioc.meta.IocEventSet)3 Method (java.lang.reflect.Method)2 ArrayList (java.util.ArrayList)2 IocException (org.nutz.ioc.IocException)2 IocValue (org.nutz.ioc.meta.IocValue)2 Field (java.lang.reflect.Field)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 Test (org.junit.Test)1 FailToCastObjectException (org.nutz.castor.FailToCastObjectException)1 IocLoader (org.nutz.ioc.IocLoader)1 Iocs.isIocObject (org.nutz.ioc.Iocs.isIocObject)1 ObjectLoadException (org.nutz.ioc.ObjectLoadException)1 ObjectProxy (org.nutz.ioc.ObjectProxy)1 ValueProxy (org.nutz.ioc.ValueProxy)1 InjectName (org.nutz.ioc.annotation.InjectName)1 DefaultWeaver (org.nutz.ioc.weaver.DefaultWeaver)1 FieldInjector (org.nutz.ioc.weaver.FieldInjector)1