你都可以注入什么
你可以向对象注入值的位置有两个
- 构造函数参数
- 属性
向构造函数里注入参数
你的 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 中的路径
注意: 如果是CLASSPATH路径,这个文件就不能打包进一个jar文件里面
数组或容器
如果你对象某个字段是数组,集合,或者 Map, 用 JSON 可以很自然为其设置值,不是吗?
Java 调用
这是个极度灵活的注入方式,它几乎可以让你 做任何事情。 因为它允许你直接调用一个 JAVA 函数。
更详细的说明,请参看 org.nutz.ioc.val.JavaValue Git@OSC镜像的 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 接口,提供了更高级的方法