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
Make sure you have enabled proxyTargetClass on, like:
@EnableTransactionManagement(proxyTargetClass = true)
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"/>
use interface AdminService
rather than the implements.
this error caused by Annotation @Transactional
, Spring
makes a proxy for AdminService
at Runtime
.
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.
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" />
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
.............
...................
}