需求是在使用SpringSecurity框架在进行用户认证时,需要实现Spring框架的接口UserDetailsService,在这里涉及两个问题
问题一:UserDetailsService的实现类如何实例化,是实例化到SpringMVC子容器中还是实例化到Spring父容器中
解决:这个接口的实现类最终要给SpringSecurity框架使用,SpringSecurity最终是要被实例化进Spring这个父容器中的,所以UserDetailService的实现类也必须要实例化进Spring父容器中,但是SpringMVC框架中的类都是由DisPatcherServlet前端控制器调用SpringMVC.xml扫描最终被实例化进SpringMVC这个Spring容器的自容器中,父容器是无法使用子容器中的类的,所以需要在SpringSecurity.xml中通过<bean></bean>标签的方式实例化进Spring父容器中,这样SpringSecurity框架才能使用这个对象,
问题二:UserDetailsService的实现类需要远程调用Service层的对象进行数据库查询
解决:UserDetailsService的实现类需要使用Service层的对象,同样的道理,这个对象再SpringMVC子容器中通过注解的方式远程调用可以使用,但是在父容器中不能使用子容器中的对象,所以还需要在springMVC.xml这个父容器中再去Dubbo中单独获取我想要Service层的某个实现类,获取到实现类之后,再在之前定义的<bean></bean>UserDetailsService标签中以Set注的方式注入进去.
这样就出现了子容器在SpringMVC.xml中配置Dubbo向注册中心进行消费,父容器中的SpringSecurity.xml中也配置Dubbo向注册中心进行单独的消费,两个Dubbo配置之后在启动项目的时候就会出现如下问题:
java.lang.IllegalStateException: Duplicate application configs: <dubbo:application name="pinyougou-shop-web" id="pinyougou-shop-web" /> and <dubbo:application name="pinyougou-web-shop" id="pinyougou-web-shop" />
在经过漫长的比对和测试之后找到了问题的所在:两个Dubbo的<dubbo:application name="XXX" />中的name属性必须一致,因为一个消费者配置了两个名字不同的Dubbo消费,就会认为是两个消费者,必然报错,解决办法是让这两个Dubbo中的name属性一致,声明我这是一个消费者,具体如下:
SpringSecurity.xml中引入的Dubbo配置:
<!-- 引用dubbo 服务 -->
<dubbo:application name="pinyougou-web-shop" />
<dubbo:registry address="zookeeper://192.168.200.128:2181"/>
<dubbo:reference id="sellerService" interface="cn.itcast.core.service.SellerService" >
</dubbo:reference>
SpringMVC.xml中引入的Dubbo配置:
<!--配置服务消费者-->
<!--服务消费者的name-->
<dubbo:application name="pinyougou-web-shop"/>
<!--zookeeper的 地址-->
<dubbo:registry address="zookeeper://192.168.200.128:2181"/>
<dubbo:annotation package="cn.itcast.core.controller"/>
<!--超时全局设置 10分钟 check="false" 不检查服务提供方 -->
<dubbo:consumer timeout="600000" check="false"/>
总结:这两个配置文件的name属性必须一致