Spring Bean Non-Proxy Injection

Spring Version : 3.2.4.RELEASE and 3.2.9.RELEASE

Mockito Version : 1.8.5

I tried to submit H2 tests to an old project for integration testing, and I had some problems. Due to the way transactions were propagated, I needed to mock a class made in a car race. I have done this before, but now I am having serious problems. When the test is initialized, the following error message appears:

org.springframework.beans.factory.BeanCreationException: error creating bean named "com.stuff.XMLITCase": resource injection could not be started; The nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: A Bean named 'TheProcessor' must be of type [com.stuff.XMLBatchFileProcessor], but in fact it was of type [$ Proxy118]     in org.springframework.context.annotationProcessMonnostationCommonnnot .postProcessPropertyValues ​​(CommonAnnotationBeanPostProcessor.java:307)

Diving into this a little deeper, it turns out that the bean is actually a proxy server. If we check AbstractBeanFactory (round line 239), we will see a proxy:

sharedInstance = {$ Proxy117 @ 7035} " com.stuff.XMLBatchFileProcessor@66c540d0 " h = { org.springframework.aop.framework.JdkDynamicAopProxy@7039 }

The only problem: I do not know where this comes from. I went through configuration and dependencies and cannot find anywhere that this should happen.

Project setup

Unfortunately, I cannot give an example project for this, but I will go through my test configuration. I have a root class that I distribute for tests:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/spring/spring-test-context.xml"})
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
public abstract class AbstractIntegrationTest {
}

It just loads into the spring configuration and rolls back the transactions after each test.

The spring configuration is nothing strange either, although there is one difference between my other module and this. This is a transaction manager and a factory session:

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="hibernateSessionFactory"/>
</bean>

<bean id="hibernateSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
...
</bean>

In my other module, I use entityManagerFactory and another transaction manager:

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
...
</bean>

@Service:

@Service(value = "TheProcessor")
public final class XMLBatchFileProcessor extends BatchFileProcessor implements IXMLBatchProcessor {

, :

public class XMLITCase extends AbstractIntegrationTest {

    @Resource(name = "TheProcessor")
    @InjectMocks
    private XMLBatchFileProcessor xmlProcessor;

    @Mock
    private ProcessHelper processHelper;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void test() throws Exception {
        Assert.assertNotNull(xmlProcessor);
    }

}

XMLBatchFileProcessor , . bean . , @Resource , .

. factory , , - .

, , xmlProcessor @Transactional, , . final CGLib , Mockito bean, initMocks(this) . CGLib beans spring, Mockito.

Mockito spring @Transactional?

0
1

, , - @Transactional, . , , - - :

, AbstractIntegrationTest:

/**
 * Checks if the given object is a proxy, and unwraps it if it is.
 *
 * @param bean The object to check
 * @return The unwrapped object that was proxied, else the object
 * @throws Exception
 */
public final Object unwrapProxy(Object bean) throws Exception {
    if (AopUtils.isAopProxy(bean) && bean instanceof Advised) {
        Advised advised = (Advised) bean;
        bean = advised.getTargetSource().getTarget();
    }
    return bean;
}

@Before:

@Mock
private ProcessHelper processHelper;

@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);

    IXMLBatchProcessor iXMLBatchProcessor = (IXMLBatchProcessor) unwrapProxy(xmlProcessor);
    ReflectionTestUtils.setField(iXMLBatchProcessor , "processHelper", processHelper);
}

@Autowired , .

+9

Source: https://habr.com/ru/post/1651659/


All Articles