假如你现在还在为自己的技术担忧,假如你现在想提升自己的工资,假如你想在职场上获得更多的话语权,假如你想顺利的度过35岁这个魔咒,假如你想体验BAT的工作环境,那么现在请我们一起开启提升技术之旅吧,详情请点击http://106.12.206.16:8080/qingruihappy/index.html
第一步,根据浏览器来找到对应的上传的类和方法ManualOpenController和uploadInfo
1 manualOpenManage.htm 2 ManualOpenController 3 <bean id="manualOpenController" 4 class="com.bill99.seashell.boss.appcontroller.intra.manualoperator.ManualOpenController"> 5 <property name="manualOpenFactory"> 6 <ref bean="manualOpenFactory" /> 7 </property> 8 同时也把manualOpenFactory给注入了进来
第二步,看这个方法里面进行了什么操作(注意上面注入进来的工厂)
ManualOpenService manualOpenService = manualOpenFactory.getManualOpenService(params);
关键看这一步就是来看一下manualOpenFactory里面都有什么呢。
我们这时候来看一下已经在容器中的manualOpenFactory都封装了什么
<bean id="manualOpenFactory"
class="com.bill99.boss.domain.service.manualopen.ManualOpenFactory">
<entry key="add;crm-flow-1;7035" value-ref="crmManualOpenService"></entry>
这时候我们根据页面传过来的参数确定就是crmManualOpenService这个类,就是普通账户上传下载的时候要求的参数来确定是crmManualOpenService
第三步,去到crmManualOpenService这个类中来。
error = manualOpenService.uploadExcel(request, userName);
这句代码其实就是
error = crmManualOpenService.uploadExcel(request, userName);
而crmManualOpenService在配置中又进行了下面的处理
<bean id="crmManualOpenService" class="com.bill99.boss.domain.service.impl.manualopen.crm.CrmManualOpenServiceImpl">
<property name="crmManualOpenServiceMap">
<entry key="DSGA" value-ref="crmOrdinaryAccountService"></entry>
那我们现在就去CrmManualOpenServiceImpl这个类中来看看都有什么业务逻辑
第四步,CrmManualOpenServiceImpl
ManualOpenService processService = crmManualOpenServiceMap.get(productCode);
根据productCode来确定了对应的实体类就是crmOrdinaryAccountService
processService.uploadExcel(request, userName);
上面一行代码的意思就是crmOrdinaryAccountService.uploadExcel(request, userName);
那我们来看看crmOrdinaryAccountService这个类在xml中都处理了什么
<bean id="crmOrdinaryAccountService" class="com.bill99.boss.domain.service.impl.manualopen.crm.CrmOrdinaryAccountServiceImpl">
<property name="approveFlowNoticeService" ref="approveFlowNoticeServiceXyf"></property>
第五步,我们现在去到CrmOrdinaryAccountServiceImpl这个类中看它进行了什么业务逻辑的处理
response = approveFlowNoticeService.notify(r);
那我们就知道approveFlowNoticeService其实就是approveFlowNoticeServiceXyf
第六步,那么approveFlowNoticeServiceXyf又是什么呢。
1 <mdp:reference id="approveFlowNoticeServiceXyf" 2 interface="com.bill99.boss.mdp.client.service.ApproveFlowNoticeService" 3 destination="notify.mdp.coe.dpm.flownode.notice" concurrency="5" 4 connection-factory="seashellConnectionFactory" timeout="60000"> 5 </mdp:reference>
在这里要注意的就是destination="notify.mdp.coe.dpm.flownode.notice" 这个是消息队列的唯一标示,其它应用就是根据它去找对应的传送的内容的。
<mdp:reference这个开始的就说明是消息生产者。
因为消息队列的xml文件是先于approveFlowNoticeService.notify(r)这句代码从在容器当中的,当代码执行到这一行是就会去容器中寻找
approveFlowNoticeService这个接口对应的管道,当他找到自己唯一的管道notify.mdp.coe.dpm.flownode.notice,就会把消息传递到拥有同样管道notify.mdp.coe.dpm.flownode.notice中来。
形象的说法就是说A国有自己的铁路轨道,现在想把火车开到B国去,但是B国必须要有一个和A国相公规格的轨道,火车才能开过去,而这个规格就是notify.mdp.coe.dpm.flownode.notice
假如没有的话,或者另一个存在同样管道的应用关闭的时候就会等待,但是也可同样设置了一个等待的的时间,假如超过了这个时间就会报出传递消息队列失败的提示。
第七步,那我们现在去另一个应用中来寻找这个管道或者轨道
我们现在在app-coe-boss-mdp中找到了下面的配置
1 <mdp:service id="approveFlowNoticeServiceSupply" 2 interface="com.bill99.boss.mdp.client.service.ApproveFlowNoticeService" 3 destination="notify.mdp.coe.dpm.flownode.notice" ref="auditNoticeService" 4 concurrency="5" connection-factory="bossServiceConnectionFactory"> 5 </mdp:service>
1:注意了以这种形式开头的就是消费之<mdp:service 。
2:ref="auditNoticeService 就是消费的指向的id
我们现在去找一下auditNoticeService对应的实现是什么
<bean id="auditNoticeService" class="com.bill99.boss.face.receive.AuditNoticeServiceImpl">
第八步,现在来看看AuditNoticeServiceImpl具体做了什么
public class AuditNoticeServiceImpl extends AbstractMessageHandleService implements ApproveFlowNoticeService {
注意消息的消费者一定要实现ApproveFlowNoticeService这个接口的
@Override
public Response notify(NodeNotifyRequest request) {
那我们就可以看到消息就被传递过来了
补充:
为了便于管理,我们一般会把中间这个共同的接口类 也有点类似于水管的作用的ApproveFlowNoticeService接口会统一放到一个jar包中去,所以假如第一眼看上去这个jar包就是孤零零的放在那的,假如单纯的看这个jar包的话,我们看不出来它是干什么用的,就是从那个应用过来的,又要到那个应用中去。