简体   繁体   English

如何自动连接交易类?

[英]How to autowire on transaction class?

Class file: 类文件:

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

Xml file: xml文件:

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

Test File: 测试文件:

@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(){
       ...
    }

Exception: 例外:

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

If I remove @Transactional(propagation=Propagation.REQUIRES_NEW) from the Class file then it will allow me to autowire my class object. 如果我从类文件中删除@Transactional(propagation=Propagation.REQUIRES_NEW) ,那么它将允许我自动连接类对象。 I was wondering is there to autowire a transactional? 我想知道是否可以自动连接事务? maybe by its type but I don't know how as this is a transactional. 也许按其类型,但我不知道这是如何处理的。

If you add the Transactional annotation to your class, Spring will create a proxy for that class to do the transaction logic. 如果将Transactional注释添加到您的类,Spring将为该类创建一个代理来执行事务逻辑。 If the bean implements an interface, Spring will create a JDK based proxy which implements all interfaces of the bean. 如果bean实现一个接口,Spring将创建一个基于JDK的代理,该代理实现bean的所有接口。 Thus the type of the proxy is in your case Service and not ServiceImpl . 因此,代理的类型在您的情况下是Service而不是ServiceImpl

There are 2 solutions: 有两种解决方案:

1: Change the field type of the autowired field to the interface: 1:将自动装配字段的字段类型更改为接口:

@Autowired
private Service service;

2: Configure Spring to use CGLIB based proxies. 2:将Spring配置为使用基于CGLIB的代理。 Those proxies extend the bean class and so they have the same type as the bean class itself. 这些代理扩展了bean类,因此它们具有与bean类本身相同的类型。 This can be done either with the following annotation and it's attribute, if you use that: 如果使用此注释,则可以使用以下注释及其属性来完成:

@EnableTransactionManagement(proxyTargetClass = true)

Or if you use XML configuration for the transaction manager: 或者,如果您将XML配置用于事务管理器,则:

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

You can read more about the proxies etc. in the Spring docu: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html#tx-decl-explained 您可以在Spring文档中了解有关代理等的更多信息: http : //docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html#tx-decl-explained

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM