BeanNotOfRequiredTypeException due to autowired fields

前端 未结 9 1224
长发绾君心
长发绾君心 2020-12-02 12:07

I\'m still new to Spring MVC and while building my test project, I got this message from Tomcat logs:

SEVERE: Exception sending context initialized event to          


        
相关标签:
9条回答
  • 2020-12-02 12:45

    Make sure you have enabled proxyTargetClass on, like:

    @EnableTransactionManagement(proxyTargetClass = true)
    
    0 讨论(0)
  • 2020-12-02 12:48

    I also have met the problem when execute unit test

    I created a mock service to implement the real service to override some method for easy to test some user case

    @Component
    public static class FooServiceImplMock extends FooServiceImpl {
        @Override
        protected void bar() {
            // do some specific loginc here 
        }
    }
    

    but when execute the test method

    @Autowired
    private Foo1ServiceImplMock foo1ServiceImplMock;
    

    I got below error

    Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'fooServiceImplTest.FooServiceImplMock' is expected to be of type 'com.foo.business.impl.FooServiceImplTest$FooServiceImplMock' but was actually of type 'com.sun.proxy.$Proxy97'
    

    Reason:

    There is method in FooServiceImpl used @Cacheable

    @Cacheable("eventTypes")
    

    And from javadoc of EnableCaching I know

    org.springframework.cache.annotation.EnableCaching 
    boolean proxyTargetClass()
    
    Indicate whether subclass-based (CGLIB) proxies are to be created as opposed to standard Java interface-based proxies. The default is false.
    

    So the resolve manner is explicitly to specify use CGLIB in spring application contenxt

     <cache:annotation-driven proxy-target-class="true"/>
    
    0 讨论(0)
  • 2020-12-02 12:50

    use interface AdminService rather than the implements.

    this error caused by Annotation @Transactional, Spring makes a proxy for AdminService at Runtime.

    0 讨论(0)
  • 2020-12-02 12:51

    I also had this problem with some @SpringBootTest classes that were testing endpoints. The endpoints had a dependency on a DB Service that has @Transactional on a few methods.

    Because of the @Transactional, Spring intercepts that and creates a proxy class, so Spock (or junit) would struggle to inject the correct mock.

    My workaround was to push the DB Service down one layer and have plain Spock tests around the middle layer which aren't affected by this.

    0 讨论(0)
  • 2020-12-02 12:52

    When your service class implements some interface, spring by default takes proxy by JDK, that's why you get that error, so you can solve that problem whether using @Autowired over the interface or enabling the CGLIB proxy.

    I solved that problem enabling CGLIB proxy using proxy-target-class attribute in my spring application context

    <tx:annotation-driven proxy-target-class="true"
            transaction-manager="transactionManager" />
    
    0 讨论(0)
  • 2020-12-02 12:54

    I have facing same issue but I solved the problem with the following workaround:

    Please replace your implementation class with interface. For example:

    class Abc
    {
     @Autowire
     private Boy boy // remove @BoyImpl
    
    .............
    ...................
    }
    
    0 讨论(0)
提交回复
热议问题