Ioc

优质
小牛编辑
122浏览
2023-12-01

Ioc 实际上一种将应用的耦合集中在一起管理的一种程序结构设计方式。耦合集中的具体形式
一般是各种格式的配置文件。比如 Spring 就有它自己的配置文件格式的规定。

Nutz.Ioc 在设计之初就没有特别假定用户会把配置文件存成某种特定的格式,关于这点,各位
可以参看 定义自己的配置文件格式 一文。

同时,我们发现,在实际应用的时候,应用程序的耦合大概分做两种:

  1. 千秋万载,基本不变
  2. 部署之时,可能改变

第一种耦合关系,其实更适合写成 Annotation,这样程序发布之后就不必担心人为的错误修改了。
而第二种则更适合写在配置文件里,你们的部署工程师可以看着你提供的小文档,根据客户现场的
情况调整你的应用的各种参数。

如果将这两种耦合关系都写在配置文件里,首先部署工程师会看到一大堆你都可能忘记是什么意思
的配置信息,当这些符号映入眼帘之时,恐惧会瞬间将TA吞没,嚼的骨头都不剩。
是的,这就是面对陌生的事物,正常人类很正常的一种反应,怪不得他不是吗?

或者可怜的部署工程师手里拿的是你几个星期吐血写出来的长长的系统参数手册,
那么写这个手册之前,感到恐怖的可能就是你了,我亲爱的同学。
之后,他在鼓起勇气阅读的之前,通常也会倒吸一口凉气。

当然,人的智慧就是在这过程中得到了淬炼,你的意志力,你的智慧,都会得到不同程度的升华。
但是 Nutz 这个小框架开发的初衷并不是希望锻炼你,折磨你,事实上,它希望尽一切可能,
让你远离这种锻炼...

...为此,我们也提供一个复合加载器,你可以将你的耦合关系写在配置文件中,或者Annotation
中,怎样分配则由亲爱的程序员同学你来亲自决定。

复合加载器的使用方法

复合加载器非常简单,似乎只花了 Wendal 同学不到 1 个小时的时间,因为它本身并不做任何
事情,它只是调用其他的加载器:

ComboIocLoader loader = new ComboIocLoader("*js",
                                               "ioc/dao.js",
                                               "ioc/service.js",
                                               "*anno",
                                               "com.myapp.module",
                                               "com.myapp.service",
                                               "*tx",
                                               // @Async注解,异步执行.
                                               "*async");

如上面的例子,组合加载器,组合了3个 Ioc 加载器,一个是 JsonLoader,一个是
AnnotationIocLoader, 一个是AOP事务的TransIocLoader(1.b.52新增), 一个异步注解加载器。

ComboIocLoader 的构造函数是个字符串形变参数组,所有的参数,如果以星号 "*" 开头,
则被认为是加载器的类型,后面的参数都作为这个加载器构造函数的参数,直到遇到下一个
星号 "*" 开头的参数。

上面的例子,实际上为 Ioc 容器准备了这两个加载器,第一个是 JSON 加载器,它从 dao.js 和
service.js 这两个配置文件中读取容器对象的配置信息。 而另外一个 Annotation 加载器,从
会扫描包 com.myapp.module 以及 com.myapp.service 已经其下的子包,如果发现有
容器对象(声明了 @IocBean 注解,详情请看 Ioc - Annotation 加载器)
就会加载。

并且这两个加载器的优先级为

排在前面前面的加载器更优先

在本节的例子中, JsonLoader 加载器比 AnnotationIocLoader 更加优先.
就是说,如果两个加载器都加载了同名对象,则以 JsonLoader 的为准

在 Mvc 中的用法

在 Nutz.Mvc 中,Ioc 容器是由 IocProvider 接口来提供的,所以,每个加载器都由一个类似
的 IocProvier 实现。比如 ComboIocLoader,也就有一个 ComboIocProvider。

但是,请千万要注意: 对于 ComboIocProvider:

它组合的依然是其他 IocLoader

而不是

其他 IocProvider

下面给个例子:

@IocBy(type = ComboIocProvider.class,
       args = {"*js",
               "ioc/dao.js", 
               "ioc/service.js", 
               "*anno", 
               "com.myapp.module",
               "com.myapp.service"
        })
public class MainModule {
    ...

它是什么意思呢? 不解释,你懂的。

现在你都可以复合什么?

  • XmlIocLoader
  • JsonLoader
  • AnnotationIocLoader
  • MapLoader
  • TransIocLoader
  • AsyncAopIocLoader
  • PropertiesIocLoader
  • 所有实现的 IocLoader接口的类

类名的简写

js         --> org.nutz.ioc.loader.json.JsonLoader
json       --> org.nutz.ioc.loader.json.JsonLoader
xml        --> org.nutz.ioc.loader.xml.XmlIocLoader
annotation --> org.nutz.ioc.loader.annotation.AnnotationIocLoader
anno       --> org.nutz.ioc.loader.annotation.AnnotationIocLoader
tx         --> org.nutz.aop.interceptor.ioc.TransIocLoader  #无参数
trans      --> org.nutz.aop.interceptor.ioc.TransIocLoader  #无参数
async       --> org.nutz.aop.interceptor.async.AsyncAopIocLoader #可以带一个线程池大小的参数
props       --> org.nutz.ioc.loader.properties.PropertiesIocLoader # 通过properties文件定义ioc bean
properties --> org.nutz.ioc.loader.properties.PropertiesIocLoader

插件加载(基于Ioc或Aop的插件)

从1.r.57开始,符合以下命名规则的插件类名,都可以直接使用缩写.

// 插件名称quartz, 那么对应以下类名
org.nutz.integration.quartz.QuartzIocLoader
org.nutz.integration.quartz.QuartzAopConfigure
org.nutz.plugin.quartz.QuartzIocLoader
org.nutz.plugin.quartz.QuartzAopConfigure
// 不保证先后顺序,所以不要同时出现2个.