【问题标题】:How to autowire on transaction class?如何在交易类上自动装配?
【发布时间】:2015-10-20 23:43:44
【问题描述】:

类文件:

@Transactional(propagation=Propagation.REQUIRES_NEW)
public class ServiceImpl implements Service {
...
}

Xml 文件:

...
<bean id="service" class="com.sky.core.engine.impl.ServiceImpl">
...

测试文件:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("testConfig.xml")
public class ServiceImplTest {

    private static final Logger log = Logger
            .getLogger(ServiceImplTest.class);

    @Autowired
    private ServiceImpl service;

    @Test
    public void test(){
       ...
    }

例外:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.sky.core.engine.comp.impl.ServiceImplTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.sky.core.engine.impl.ServiceImpl com.sky.core.engine.impl.Service; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.sky.core.engine.comp.impl.ServiceImpl] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1146)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:376)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:110)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:290)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.sky.core.engine.impl.ServiceImpl.ServiceImpl com.sky.core.engine.impl.ServiceImpl; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.att.lpp.pa1.core.engine.comp.impl.EndPointServiceImpl] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:517)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286)
    ... 26 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.sky.core.engine.comp.impl.ServiceImpl] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:988)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:858)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:770)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:489)
    ... 28 more

如果我从类文件中删除@Transactional(propagation=Propagation.REQUIRES_NEW),那么它将允许我自动装配我的类对象。我想知道是否有自动装配交易?也许按它的类型,但我不知道这是如何交易的。

【问题讨论】:

    标签: java spring hibernate autowired


    【解决方案1】:

    如果您将 Transactional 注释添加到您的类,Spring 将为该类创建一个代理来执行事务逻辑。如果 bean 实现了一个接口,Spring 将创建一个基于 JDK 的代理来实现 bean 的所有接口。因此,代理的类型在您的情况下是 Service 而不是 ServiceImpl

    有两种解决方案:

    1: 将自动装配字段的字段类型更改为接口:

    @Autowired
    private Service service;
    

    2:配置 Spring 以使用基于 CGLIB 的代理。这些代理扩展了 bean 类,因此它们具有与 bean 类本身相同的类型。这可以通过以下注释及其属性来完成,如果您使用它:

    @EnableTransactionManagement(proxyTargetClass = true)
    

    或者,如果您为事务管理器使用 XML 配置:

    <tx:annotation-driven proxy-target-class="true" transaction-manager="txManager"/>
    

    您可以在 Spring 文档中阅读有关代理等的更多信息:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html#tx-decl-explained

    【讨论】:

      猜你喜欢
      • 2017-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-26
      • 2022-08-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多