28. Service 框架和 Spring 框架的异同
1: Spring 是个更通用的容器,容器装载的 Bean
可 以是任何类型对象。而 Service 容器中装载
的是 Service 对象。
2: Spring 容器中的对象可以不必知道容器,而
Service 容器中 service 对象是紧密和容器耦合的
。
29. Service 框架究竟有没有实现“依
赖注入”
《 Service 框架指南》中说 Service 框架不支持“注入”,而 Module 中却
用到了注入。
宝宝的答复:
Service 框架不支持注入。但是应工程师要求,在
screen/action/control 等部
件中加入了注入功能,是用 cglib 直接实现的,和 service 框
架无关。
另外,我目前在做的工作是,将 webx 移植到纯 spring 框架
中,抛弃 service 框架,
因此注入从此不是问题了。
51. 关于 PullServie
实现 Pull-MVC 的设计模式
怎么理解 Pull-MVC, 和 push 的不同之处?
What this entails is the ability to create an
object that is able to “pull” the required
information out at execution time within the
template.
52. 2.4 WebX 业务层 (BIZ
层)
1 :业务层的 Service 容器。是如何创建的?
2 : AO,BO,DAO 都在 Spring 容器中。
AO 每次请求时都是一个新的实例?
BO 是一些通用逻辑模块,可供多个 AO 调用。
53. 用 Singleton 启动 Service
容器
为了分离 WEB 层和业务层的对象,我们常常
将 WEB 层的 Service 容器和业务层的 Service
容器彻底分开。这样, WEB 层的 Spring 容器
也随之和业务层的 Spring 容器彻底分开了。如
图所示:
54. Web 层和 BIZ 层分离
Web 层 Service 容器
Car1 Car2
Spring 容器 Spring 容器
Dispatcher Dispatcher
Biz 层 Service 容器
Spring 容器
AO BO
55. 用 Singleton 启动 Service 容
器
上图中的 CommandDispather 在初始化中,
会调用 SingletonServiceManagerLoader 来
启动一个独立于 WEB 层的业务层 Service 容
器,再从中取得业务层的 Spring 容器。所有
业务层的对象,都配置在这个 Spring 容器中。
请记住,这是一个 Singleton ,意味着业务
层的 Spring 容器只会被初始化一遍。
62. 宝宝《 Webx Modules 的装载以及依赖注入》
中说:
……
然而还有一个问题。在我们的常见应用中,
web 层和 biz 业务层是分离的, web 层的
spring 容器和 biz 层的 spring 容器也是分离
的。上面的配置只能拿到 web 层 spring 容
器中的内容,不能拿到 biz 层 spring 容器的
内容,怎么办呢?方法很简单:在 web 层的
spring 容器中包含 biz 层的 spring 容器的引
用。
63. 既然是分层的 (web 层和 Biz 层分别存在各自的 Service 容器中 ) 。
Web 层 spring 容器 又如何得到 biz 层的 Spring 容器引用呢?
我看你后边的配置, web 层是通过获取 Biz 层的 Service 容器引
用 再去获得 Biz 层 Spring 容器的,
<beans>
<bean id=“bizBeanFactory”
class=“com.alibaba.service.spring.support.SingletonBeanFactorySe
rviceBean”>
<property name=“serviceConfig”
value=“biz/services.xml”/><!-- 指向 biz 层 service 容器 -->
</bean>
</beans>
那样的话,两个 Service 容器不就完全耦合了吗,
还要 CommandDispatcher 干嘛。
64. 实际在我们的 webx-default 中对 sub-instance 也存在一个对 biz
层 Spring 容器的引用:
<service name=“BeanFactoryService”
class=“com.alibaba.service.spring.DefaultBeanFactoryService”>
<property name=“bean.descriptors”>
<value>exodus2/bean/biz-delegate.xml</value>
<value>exodus2/bean/web-tool.xml</value>
</property>
</service>
web-tool.xml 里面配置了 WebApplicationContextUtilsBean ,里面 setter 了
serviceConfig:alibaba-biz-service.xml 。该 utilBean 初始化时会通过调用
SingletonServiceManagerLoader.getInstance(
bootstrapResourceLoaderService, serviceConfig, initAll);
获取 biz 层的 Service 容器的单实例引用,进而获取 biz 层的 Spring 容器引用。
我们就可以通过该 UtilBean 来访问 biz 层的 spring 容器。
65. Exodus2 的中实际场景(不完整)
Car1 Car2
Spring 容器 Spring 容器
UtilBean UtilBean
CommandDispatcher
Biz 层 spring 容器
AO BO
66. 思考:
这样岂不是将 web 层的 Service 容器和 Biz 层的 Service
容器耦合在了一起?
Michael zhou:
Command Dispatcher 是可以访问到业务层的代码的,按理说,这应
该是唯一的访问
业务层 spring 容器的方法。
你看到我把 bizBeanFactory 注入到 web 层容器中,说实在这种做法
是不太完美的。
但这也是对实际需求的一种妥协。因为有一些公用对象(非业务层
和数据访问层对
象,如 AO 、 DAO 等),需要放在一个大家都能访问到的地方。但
当你要访问业务对
象( AO 、 DAO 等)时,仍然应该通过 command dispatcher 来走
。
70. Biz 层的 CommandDispatcher:
除了 web 层和 biz 之间使用 CommandDispatcher, biz 层内部之间也使
用了 CommandDispatcher
比如发邮件的情况, web 层 dispatcher 到 biz 层的 SendMailBO ,它
又会通过 biz 层的 dispatcher 交给 JMS
biz 层这时用的 dispatcher 是异步消息队列的方式。
Web-CommandDispatcher
EJB 容器
Biz-Serverice 容器
Spring 容器
BO Biz-dipatcher AlibabaWebxQueue ???
杨亮:能不能把 BeanFactoryService 也实现 MultiInstance 接口,让 car 的每个 BeanFactoryService 实例都引用 main 的 BeanFactoryService 的实例 阿甘:一些全局的 Service 比如 RunDataService 会依赖其他 Service ,所以全局会设置很多 Service
宝宝意思是 service 容器并没有实现 service 之间的注入功能,比如: ServiceA 依赖于 ServiceB 的,需要通过 ServiceManager.getService(ServiceB.class) 。但 ModuleLoaderService 利用 ModuleFactory 实现对 Module 的依赖注入功能
关于 Push MVC Model The current encouragement that Turbine gives to developers is to do a mapping between one Screen (Java) and one Template (WM or V). The way it works is that you build up a Context object that is essentially a Hashtable that contains all of the data that is required to render a particular template. Within the template, you refer to that data in order to format it for display. I will refer to this as the &quot;Push MVC Model.&quot;
杨亮: AO 是 prototype ,每次请求都新建一个实例,因为他有个 command 引用。 Command 就是 web 调用 biz 时新建 CommandSupport 实例。 里面存储着 web 层传过来的参数集。
我还是没理解他说的妥协是怎么回事? 宝宝后来举了一个 DWR(java 层 ) 的用法,假设 car1 和 car2 都需要使用 DWR 这个对象,并且 DWR 又会操作 Biz 层的对象。 那么最简单的方式就是把 DWR 放到 Biz 层的 Spring 容器中,并提供 car1 和 car2 到 DWR 的访问途径。 Web 层到 Biz 层 Spring 容器的引用,决不能被当作 CommandDispatcher 的快捷方式来使用。
sessionDispatcher 引用一 个 ejb/CommandDispatcherSLSB 的 ejb 实例。而这个 ejb 实例 ( com.alibaba.biz.command.dispatcher.ejb.slsb.CommandDispatcherBean ) 也只是代理了 commandDispatcherLogic 。 public Result execute(Command command) { Result result = getCommandDispatcherLogic().execute(command); }
宝宝:也可能是后续维护的人员弄错了。应该一个就够了。 阿甘:如果只用一个全局的话,也不排除有没有其他陷阱,比如会否用到 ResourceLoaderService ,每个 car 是不同的。
Apache 除了打点用到,有其他作用么? Exodus2 中应该没有静态页面吧?
iBatis 的配置,似乎只对少量业务使用了高速缓存。 Type=LRU
Delta Index 增量索引,索引的信息并不完整,所以还不能替代每天晚上的 Build Index 目前数据库 offer 数据在 2 亿多,还能承受 Build Index ,未来可能会面临压力。