2013-12-10 2 views
1

У меня есть Bean, настроенный в моем диспетчере-servlet.xml. В классе я могу успешно вставить этот компонент с помощью автообновленной аннотации, например.Spring 3 Autowire Bean, который использует интерфейс

class test { 
    @Autowired 
    TestBean testBean; 
} 

Но как только я добавить интерфейс с «орудиями» ключевым словом testbean, я получаю IllegalArgumentException:

java.lang.IllegalArgumentException: Невозможно установить com.test.TestBean поля ком. test.myclass.testBean to com.sun.proxy. $ Proxy26.

При удалении ключевого слова «реализует», включая имя интерфейса, все снова работает отлично.

+0

Можете ли вы показать декларацию класса для интерфейса и класса, на который вы ссылаетесь? Является ли TestBean классом или интерфейсом? Какой интерфейс вы добавляете? – jalynn2

+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] 

Для этого примера, весна будет принимать Example боб (объявленный в контексте), решать, что ему нужно прокси его, используйте Example класса, и создать все, что необходимо InvocationHandler, обратившись к компоненту в качестве цели для вызова метода.

Что нужно учитывать, так это то, что объект, который возвращается Proxy.newProxyInstance(..), не имеет типа Example. Он имеет тип Proxy и любого типа интерфейсов Example. Вот почему Spring не может использовать прокси-объект для установки поля (через отражение) типа Example или TestBean в вашем случае.

Два способа заставить его работать. Во-первых, извлеките интерфейс из своего класса, если он еще не имеет его и использует поле типа интерфейса.

Во-вторых, вы можете настроить свой контекст для использования прокси CGLIB, который может проксировать по типу класса.

+0

Привет. Спасибо за Ваш ответ. Iam много тестирует здесь :-) ... Что значит «использовать поле типа интерфейса». Существуют ли другие способы использования интерфейсов, например, с «инструментами». Это было бы новым для меня :-) ... –

+0

@ J.Archer Нет, я имею в виду вместо «частного примера примера» в качестве переменной-члена, у вас будет «private Proxied example;».Прокси имеет все типы интерфейса вашего объекта, но не имеет типа класса. См. Вывод моего фрагмента кода. –

+0

Geeze ... более года без голосов? –

0

в XML:

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

убедиется испытание в вашем весне боб XML, то вы можете сделать

@Autowired 
Test test; 

test.testBean.doAnything(); 

вещи, чтобы заметить здесь, что вы должны intatiate своего класса Test.

+0

Ваш второй фрагмент вызовет 'NullPointerException'. –

+0

Хорошо, изменил. Это работает. – user1275645

Смежные вопросы