По умолчанию Spring применяет AOP с помощью прокси-классов .Прокси-класс создается динамически для реализации ряда интерфейсов.Вы передаете ему объект-обработчик, который он затем вызывает, когда к нему вызывается любой из этих методов интерфейса.Вы можете прочитать Javadoc для прокси-объектов здесь .
После инициализации всех bean-компонентов в контексте приложения Spring выполнит любую необходимую последующую обработку.Это включает в себя применение рекомендаций АОП.Spring заменит bean-компонент с именем eddie
на прокси-объект, который в приведенном выше примере вызывает метод для другого объекта перед передачей вызова исходному объекту.Всякий раз, когда вы запрашиваете бин с именем eddie
, вы получаете прокси-объект вместо реального объекта.
Я не мог найти источник для класса Main
, упомянутого в нижней частивыше, но я нашел большую часть кода здесь .В любом случае, в классе Main
кажется, что вы делаете что-то вроде
Instrumentalist eddie = (Instrumentalist) appContext.getBean("eddie", Instrumentalist.class);
Метод getBean(String, Class)
контекста приложения Spring проверит, что возвращаемый компонент соответствует указанному классу, и если неткинь исключение.Это то, что произошло в вашем примере выше.Прокси-объект не является экземпляром Instrumentalist
, это экземпляр его собственного прокси-класса с именем $Proxy4
.(Этот прокси-класс не может быть подклассом Instrumentalist
, потому что все прокси-классы расширяются java.lang.reflect.Proxy
).
Прокси-классы всегда реализуют все интерфейсы, с которыми они были созданы.Spring заметит, что Instrumentalist
реализует Performer
, поэтому созданный им прокси-класс также реализует Performer
.Вы можете заменить вышеуказанную строку на
Performer eddie = (Performer) appContext.getBean("eddie", Performer.class);
, и, если вам нужно только вызвать метод perform()
для eddie
, ваш код должен работать.