Spring的接口注入

我在使用接口注入时,犯了个错误,项目运行时出现“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中时(内容如下),一开头提出的问题却出现了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- 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,这是接口注入的核心(遗憾的是,接口注入和属性注入的功能差不多,但接口使得项目的类数量变多,现如今不推崇使用接口注入)。