Spring 3使用接口的Autowire Bean

时间:2013-12-10 15:50:18

标签: spring interface javabeans autowired

我在dispatcher-servlet.xml中配置了Bean。在类中,我可以使用自动装配的注释成功注入此bean,例如

class test {
  @Autowired
  TestBean testBean;
}

但是,一旦我将一个带有“implements”关键字的接口添加到testbean,我就会得到一个IllegalArgumentException:

java.lang.IllegalArgumentException:无法将com.test.TestBean字段com.test.myclass.testBean设置为com.sun.proxy。$ Proxy26。

当删除“implements”关键字时,包括界面名称,一切正常。

2 个答案:

答案 0 :(得分:1)

您需要提供更多详细信息,例如接口类型和上下文配置,但原因如下。默认情况下,Spring使用JDK代理来添加AOP或装饰器行为,例如,@Transactional@Async

JDK代理仅适用于接口类型,而不适用于类类型。举个例子

public class Driver {
    public static void main(String[] args) throws Exception {
        final Example example = new Example();
        Proxied proxy = (Proxied) Proxy.newProxyInstance(Driver.class.getClassLoader(), example.getClass().getInterfaces(), new InvocationHandler() {
            Example target = example;
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("intercepted");
                return method.invoke(example, args);
            }
        });

        proxy.execute();

        System.out.println(proxy.getClass());
        System.out.println(proxy.getClass().getSuperclass());
        System.out.println(Arrays.toString(proxy.getClass().getInterfaces()));
    }

    static class Example implements Proxied {
        @Override
        public void execute() {
            System.out.println("Example executing.");
        }
    }

    static interface Proxied {
        void execute();
    }
}

打印

intercepted
Example executing.
class com.spring.$Proxy0
class java.lang.reflect.Proxy
[interface com.spring.Driver$Proxied]

出于本示例的目的,Spring将采用Example bean(在上下文中声明),确定它需要代理它,使用Example类'接口,并创建任何{ {1}}它需要通过引用bean作为调用方法的目标。

您需要注意的是InvocationHandler返回的对象不属于Proxy.newProxyInstance(..)类型。它的类型为Example,类型为Proxy的接口。这就是为什么Spring无法使用代理对象在您的情况下设置类型为ExampleExample的字段(通过反射)。

使其发挥作用的两种方法。首先,从类中提取一个接口,如果它没有接口,则使用接口类型的字段。

其次,您可以将您的上下文配置为使用可以按类类型代理的CGLIB代理。

答案 1 :(得分:0)

XML中的

<bean id="test" class="your.package.Test"/>

确保Test在您的spring bean XML中,然后您可以

@Autowired
Test test;

test.testBean.doAnything();

这里需要注意的是你必须要考虑你的考试课程。