Hello world
Ioc 的概念
Nutz.Ioc 从概念上是很简单:将一部分关于对象的依赖关系单独存储在某种介质里,并且 提供一个接口帮助使用者获得这些对象。
但是将依赖关系存储在什么地方呢? Spring 选的是 XML, Guice 选的 Java (硬编码)
Nutz.Ioc 核心逻辑并没有限定配置信息的存储方式,但它还是提供了一个默认的配置文件 编写方式 -- JSON。因为
- 省却了 XML 书写的烦恼
- 避免了硬编码 -- 修改配置,不需要重新编译工程
当然,你可以扩展它,提供自己的配置文件加载方式, Nutz.Ioc 不反对你这样,它甚至 有点鼓励你这样,虽然 JSON 方式的配置文件书写方式已经工作的很好了。
下面,我先以 JSON 文件为例,给大家一个 Hello World
一个简单的例子
在这个例子中,你需要一 POJO,以及一个 JSON 配置文件。 例子的源代码,你可以访问 Nutzbook 获取
POJO 源代码
package nutz.demo.ioc.book; import java.util.Calendar; public class Pet { private String name; private Calendar birthday; private Pet friend; public Pet() {} public Pet(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Calendar getBirthday() { return birthday; } public void setBirthday(Calendar birthday) { this.birthday = birthday; } public Pet getFriend() { return friend; } public void setFriend(Pet friend) { this.friend = friend; } }
这个对象有两个构造函数
Json 配置文件
与 POJO 在同一包路径下
/* * 开始写上 var ioc = { , 是为了利用 eclipse 的 javascript 编辑器的自动格式化功能 */ var ioc = { /* * 默认的,你仅仅需要直接声明每个字段的值即可,Nutz.Ioc 会为你转型 */ xiaobai : { name : 'XiaoBai', birthday : '2009-10-25 15:23:40' }, /* * 你当然也可以做更细致的设置 */ xiaohei : { type : 'nutz.demo.ioc.book.Pet', // 类型 singleton : false, // 是否为单件 args : [ 'XiaoHei' ], // 构造函数参数 fields : { birthday : '2009-11-3 08:02:14', friend : {refer : 'xiaobai'} // 指向容器里另外一个对象 } } }
调用代码
package nutz.demo.ioc.book; import org.nutz.ioc.Ioc; import org.nutz.ioc.impl.NutIoc; import org.nutz.ioc.loader.json.JsonLoader; public class HelloPet { public static void main(String[] args) { Ioc ioc = new NutIoc(new JsonLoader("nutz/demo/ioc/pet/pets.js")); Pet pet = ioc.get(Pet.class, "xiaobai"); System.out.printf("%s - [%s]\n", pet.getName(), pet.getBirthday().getTimeZone().getID()); ioc.depose(); // 关闭ioc容器. } }
控制台输出
XiaoBai - [Asia/Shanghai]
如果配置文件中声明了类型,则可不传入类型
Pet xh = ioc.get(null, "xiaohei"); System.out.printf("%s's friend is %s\n", xh.getName(), xh.getFriend().getName());
控制台输出:
XiaoHei's friend is XiaoBai
声明了 singleton: false,那么它每次获取,都会生成一个新的实例
Pet p1 = ioc.get(null, "xiaohei"); Pet p2 = ioc.get(null, "xiaohei"); System.out.println(p1==p2);
控制台输出:
false
关于进阶
我可以负责任的告诉你:你已经掌握了 Nutz.Ioc 在你开发的时候 80% 情况下所需要的知识。 当然,它还提供了更多的功能,有些功能是其他 Ioc 容器所不具备的,你可以根据自己需要来阅读,他们包括:
- 匿名对象
- 事件监听
- 你都可以注入什么
- 事件的监听
- 定义自己的配置文件格式
- AOP模型 -- NutAop的实现思路
- AOP -- 声明式切片
- 对象生命范围 -- 级联的上下文环境
- 使用XML作为配置文件格式 -- 使用XML作为配置文件格式
- 使用注解配置Ioc --使用注解配置Ioc
- 用json文件声明Aop切片 -- 在json配置文件中声明Aop及声明式事务
关于工厂方法
从1.b.51开始, nutz内置的json/xml/annotation加载器支持工厂方法了
Json写法是
{ ssdb : { type : "org.nutz.ssdbj4.spi.SSDB", // 接口或抽象类 args : ["127.0.0.1", 8888, 5000, null], factory : "org.nutz.ssdbj4.SSDBs#pool" // 类名#方法名 } }
XML写法是
<ioc> <obj name="ssdb" type="org.nutz.ssdbj4.spi.SSDB" factory="org.nutz.ssdbj4.SSDBs#pool"> <args> <str>127.0.0.1</refer> <int>8888</int> <int>5000</int> </args> </obj> </ioc>
可选属性
从1.b.51开始, nutz内置的json/xml/annotation加载器支持可选属性了
有时候,某些服务即使不存在也不会影响系统的运行,但这些属性又是ioc配置好的,这时就需要可选属性了
注解的写法是
@IocBean public class MqttService { @Inject(optional=true) protect Dao dao; @Inject protect MqttClient client; public void publish(String topic, Object data) { if (dao != null) { // 有就记录,没有就算了呗 dao.insert(new MqttHistory(topic, String.value(data)); } client.publish(topic, data); } }