标签:
我在使用接口注入时,犯了个错误,项目运行时出现“The requested resource (Servlet action is not available) is not available.”的提示。当我不经意地往控制栏里那么一瞅时,我发现了一条重要线索:“Failed to convert property value of type [com.sun.proxy.$Proxy1] to required type [com.ilovecl.news.service.impl.UsersManager] for property ‘usersManager’”。
我之所以知道有这么一条线索,还得从Spring的注入方式说起。在很久很久以前,传说中著名的java开源框架Spring有三种不同的注入类型:接口注入、属性(Setter)注入和构造函数注入。 当中的接口注入正是导致这个错误的罪恶之源,为何?请客官听我慢慢道来。
在项目里,我编写了个IUsersManager接口,里边的函数负责管理用户,我还编写了个UsersManager类(它实现了IUsersManager接口)。除了这两位,还存在着关键的第三位兄弟UsersAction类。
UsersAction类内部有一个UsersManage变量,正如代码中所示:
public class UsersAction extends DispatchAction {
  // 注入的目标是实现了接口的类
    private UsersManager usersManager;
    public UsersManager getUsersManager() {
        return usersManager;
    }
    public void setUsersManager(UsersManager usersManager) {
        this.usersManager = usersManager;
    }
当我放心地利用Spring的IOC特性,在配置文件中将UsersManager注入到UsersAction中时(内容如下),一开头提出的问题却出现了。
<!-- usersManager将会被注入UsersAction -->
<bean name="/users" class="com.ilovecl.news.struts.action.UsersAction">
  <property name="usersManager">
    <ref local="usersManager" />
  </property>
</bean>
<!-- UsersManager -->
<bean id="usersManager" parent="baseTransactionProxy">
  <property name="target">
    <bean class="com.ilovecl.news.service.impl.UsersManager">
      <property name="usersDao">
        <ref local="usersDao" />
      </property>
    </bean>
  </property>
</bean>我试图将一个实现了某个接口的类A直接注入到另一个类B中,这在Spring中是不允许的。我必须将B中的A换成接口,将UsersAction的UsersManager换成IUsersManager接口,更改后的代码如下:
public class UsersAction extends DispatchAction {
  // 注入的目标是接口
    private IUsersManager usersManager;
    public IUsersManager getUsersManager() {
        return usersManager;
    }
    public void setUsersManager(IUsersManager usersManager) {
        this.usersManager = usersManager;
    }
也就是说,一个实现了接口的类A,必须以接口的形式注入到目标B中,这样一来,目标B只需调用接口即可操作类A,这是接口注入的核心(遗憾的是,接口注入和属性注入的功能差不多,但接口使得项目的类数量变多,现如今不推崇使用接口注入)。
标签:
原文地址:http://blog.csdn.net/qiuych3/article/details/51331223