Search in sources :

Example 1 with ValueProxy

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

the class IocCustomizedValueTypeTest method test_simple_customized.

@Test
public void test_simple_customized() {
    String json = "{xb:{name:{cc:'XiaoBai'}}}";
    Ioc2 ioc = new NutIoc(new MapLoader(json));
    ioc.addValueProxyMaker(new ValueProxyMaker() {

        public ValueProxy make(IocMaking ing, IocValue iv) {
            if ("cc".equalsIgnoreCase(iv.getType())) {
                return new StaticValue("CC:" + iv.getValue());
            }
            return null;
        }

        public String[] supportedTypes() {
            return Lang.array("cc");
        }
    });
    Pet pet = ioc.get(Pet.class, "xb");
    assertEquals("CC:XiaoBai", pet.getName());
    ioc.depose();
}
Also used : NutIoc(org.nutz.ioc.impl.NutIoc) MapLoader(org.nutz.ioc.loader.map.MapLoader) IocMaking(org.nutz.ioc.IocMaking) ValueProxy(org.nutz.ioc.ValueProxy) ValueProxyMaker(org.nutz.ioc.ValueProxyMaker) IocValue(org.nutz.ioc.meta.IocValue) Ioc2(org.nutz.ioc.Ioc2) Pet(org.nutz.dao.test.meta.Pet) Test(org.junit.Test)

Example 2 with ValueProxy

use of org.nutz.ioc.ValueProxy 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 3 with ValueProxy

use of org.nutz.ioc.ValueProxy 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)

Aggregations

ValueProxy (org.nutz.ioc.ValueProxy)3 IocException (org.nutz.ioc.IocException)2 IocObject (org.nutz.ioc.meta.IocObject)2 IocValue (org.nutz.ioc.meta.IocValue)2 Field (java.lang.reflect.Field)1 Method (java.lang.reflect.Method)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 Map (java.util.Map)1 Test (org.junit.Test)1 Pet (org.nutz.dao.test.meta.Pet)1 Ioc2 (org.nutz.ioc.Ioc2)1 IocMaking (org.nutz.ioc.IocMaking)1 ObjectProxy (org.nutz.ioc.ObjectProxy)1 ValueProxyMaker (org.nutz.ioc.ValueProxyMaker)1 NutIoc (org.nutz.ioc.impl.NutIoc)1 MapLoader (org.nutz.ioc.loader.map.MapLoader)1 IocEventSet (org.nutz.ioc.meta.IocEventSet)1 IocField (org.nutz.ioc.meta.IocField)1 DefaultWeaver (org.nutz.ioc.weaver.DefaultWeaver)1