你都可以注入什么
从哪里注入?
你可以向对象注入值的位置有两个
- 构造函数参数
- 属性
向构造函数里注入参数
你的 JSON 配置文件会是这样
{ xb : { type : 'nutz.demo.ioc.book.Pet', args : ['XiaoBai'] } }
args 的值时一个数组,里面每一个元素都将对应构造函数的一个参数。当然,你 必须确保你得有这样的构造函数。每个参数按照 JSON 的规定,是用半角逗号分隔的。
向属性注入参数
你的 JSON 配置文件会是这样
{ xb : { type : 'nutz.demo.ioc.book.Pet', fields : { name : 'XiaoBai' } } }
如果你不需要写 type,那么你可以用简写模式:
{ xb : { name: 'XiaoBai' } }
值可以不仅是字符串
是的,它还可以是
布尔
{ xb : { dead: true } }
数字
{ xb : { age: 24 } }
内部对象
{ xb : { friend: { type : 'nutz.demo.ioc.book.Pet', fields : {name : 'XiaoHei'} } } }
关于内部对象 请看这里
引用
{ xb : { friend: {refer: 'XiaoBai' } } }
{refer : '另外一个对象在容器中的名称'}
将会得到容器中另外一个对象
容器自身
{ xb : { myIoc : {refer: '$Ioc'} } }
一种特殊的引用,大小写不敏感,值就是 Ioc 容器本身
对象的名称
{ xb : { myIoc : {refer: '$Name'} } }
一种特殊的引用,大小写不敏感,值就是对象的名称,即 "xb"
容器上下文
{ xb : { myIoc : {refer: '$Context'} } }
一种特殊的引用,大小写不敏感,值就是当前容器的上下文环境接口 org.nutz.ioc.IocContext
环境变量
{ xb : { name : {env : "JAVA_HOME"} } }
{env : '环境变量名'}
将会得到系统中环境变量的值
从1.b.53开始, env及sys支持数组了, 例如需要JAVA_HOME下面的/bin/java的路径,可以写为
{ xb : { name : {env : ["JAVA_HOME", "/bin/java"]} } }
注入的属性值类似于 /opt/jdk8/bin/java
如果某个环境变量不存在的时候当成空字符串,那么,在前面加个感叹号
{ xb : { name : {env : ["!JAVA_HOME", "/bin/java"]} } }
当JAVA_HOME不存在时,就会输出 /bin/java
同时也支持默认值哦,用冒号分割
{ xb : { name : {env : ["!JAVA_HOME:/opt/jdk6", "/bin/java"]} } }
文件
{ xb : { profile : {file : "/home/zozoh/tmp/name.txt"} } }
{file : '文件路径'}
可以是绝对路径,也可以是 CLASSPATH 中的路径
数组或容器
如果你对象某个字段是数组,集合,或者 Map, 用 JSON 可以很自然为其设置值,不是吗?
Java 调用
这是个极度灵活的注入方式,它几乎可以让你 做任何事情。 因为它允许你直接调用一个 JAVA 函数。
更详细的说明,请参看 org.nutz.ioc.val.JavaValue 的 JDoc
下面只是列出主要的几种应用方式
静态属性
{ xb : { oneField : {java: 'com.my.SomeClass.staticPropertyName'} } }
静态函数
{ xb : { oneField : {java: 'com.my.SomeClass.someFunc'} } }
带参数的静态函数
{ xb : { oneField : {java: 'com.my.SomeClass.someFunc("p1",true)'} } }
参数可以是任何种类的值
容器中的对象
{ xb : { oneField : {java: '$xh'} } , xh : { name : 'XiaoHei'} }
容器对象某个属性
{ xb : { oneField : {java: '$xh.name'} } , xh : { name : 'XiaoHei'} }
容器对象某个方法的返回值
{ xb : { oneField : {java: '$xh.getXXX()'} } , xh : { name : 'XiaoHei'} }
容器对象某个方法的返回值,带参数
{ xb : { oneField : {java: '$xh.getXXX("some string", true, 34)'} } , xh : { name : 'XiaoHei'} }
参数可以是任何种类的值
你可以增加自己的特殊类型
从上面你可以看到 JSON 语法的好处,非常轻巧
- 文件 --
{file: '路径'}
- 环境变量 --
{env: '环境变量名'}
- 引用 --
{refer: '对象名'}
- JAVA --
{java: '$对象名.方法名(参数1, 参数2)'}
还可以更多吗?
是的,你完全可以扩展,比如你如果想支持一种新的类型:
oneField : {scan : '扫描仪地址'}
如何支持这种新的值的类型呢?
实现一个扩展接口
实现 org.nutz.ioc.ValueProxyMaker 接口:
package nutz.demo.ioc.book; import org.nutz.ioc.IocMaking; import org.nutz.ioc.ValueProxy; import org.nutz.ioc.ValueProxyMaker; import org.nutz.ioc.meta.IocValue; import org.nutz.lang.Lang; public class ScanValueProxyMaker implements ValueProxyMaker { public ValueProxy make(IocMaking ing, IocValue iv) { if ("scan".equals(iv.getType())) { final String address = iv.getValue().toString(); return new ValueProxy() { public Object get(IocMaking ing) { // 根据 address 创建一个对象 throw Lang.noImplement(); } }; } return null; } public String[] supportedTypes() { return new String[]{"scan"}; } }
添加到 Ioc 容器中
Ioc2 ioc = new NutIoc(new JsonLoader("path/path/name.js")); ioc.addValueProxyMaker(new ScanValueProxyMaker()); // 下面,你就可以正常使用 Ioc 接口了
注意,这里使用的是 Ioc2 接口,它继承自 Ioc 接口,提供了更高级的方法