1. 背景
首先感谢 drinkjava 同学的意见, 看得出来是问题是认真思考之后提出来的. 本文将就评论中的两段意见分别作答. 在此之前先解释一下上面那段评论中的术语:
- DI – Dependency Injection – 依赖注入, 反向控制的一个特例, 指在构造对象时对象的(某些)状态不由对象类自身逻辑初始化,由 DI 框架依照环境配置以及状态上的申明注入.
- AOP – Aspect Oriented Programming – 面向切面编程, 允许使用特定技术将逻辑编织进程序结构中, 逻辑对应程序结构中特定的切点.
2. [意见一] 一个 MVC 工具为什么要引入 DI 依赖注入
你这个DI工具的出发点可能有问题,一个MVC工具为什么要引入DI依赖注入?
这个问题有两个地方值得商榷:
-
上面这个问题隐含的一个前提假设是 Act 是一个 MVC 工具. 实际上这个前提有一点问题, 我启动 Act 项目的动机是希望弄一个符合自己想法的 PlayFramework V1.x 的后继者. Play 本身除了是一个开发框架,也是一个运行时平台, Act 也是. 单单用 “MVC 工具” 来描述 Act 并不符合我自己的想法. 用 “MVC 工具” 来描述 Act 的依赖 osgl-mvc 更能够贴切一点.
-
MVC 工具为什么不能引入 DI 依赖注入. 后面 drinkjava 同学也提到 “直接引入 Spring 或 Guice 的不好吗?”, 说明 drinkjava 并不是认为 MVC 工具不能引入 DI 依赖注入, 而是认为 Act 引入的 DI 依赖注入 Genie 没有提供 AOP 功能, 而 AOP 功能在他看来是实现声明式事务必须的,所以才认为不适合.
2.1 Act 的依赖注入机制与应用
下面我们就 javadrink 同学上面的关切来谈谈 Act 的依赖注入机制与应用.
这里是来自 Wikipedia 对依赖注入的定义 “In software engineering, dependency injection is a technique whereby one object supplies the dependencies of another object“. 简单地说就是对象的状态不由自己来创建, 而是交给另外的对象来注入. 举个例子:
public class UserService {
@Inject
private Dao<User> userDao;
@GetAction("/users/{userId}")
public User get(String userId) {
return userDao.findById(userId);
}
}
上面是一个简单的 UserService 端口. 其中需要使用对应与 User
实体类的 Dao
. 在上面的代码中我们没有看到 userDao
是如何初始化的, 因为 userDao
是 Act 框架在实例化 UserService
的时候注入的. 这就是一个典型的 Act 应用依赖注入的方式. 当然 Act 对于依赖注入的使用还有其他的扩展. 我们稍后会提到.
2.1.1 为什么不用 Guice 或者 Spring
这个和Spring或Guice的功能重叠了。直接引入Spring或Guice的不好吗?
现在我来回答 drinkjava 的这个问题: “直接引入 Spring 或 Guice 的不好吗?“. 实际上在开发 Genie 之前 Act 尝试过另外两种依赖注入:
在 Act 正式发布之前, 这上面两种注入都曾经在 act 0.x 版本中进入过实际项目 (当然是老码农所在公司的 – 开坑自己先踩是老码农做开源的基本原则).最终我选择了自己开发