@Autowire奇怪的问题

Jav*_*avi 23 java spring spring-mvc autowired

自动装配时我有一种奇怪的行为

我有类似这样的代码,它的工作原理

@Controller
public class Class1 {
    @Autowired
    private Class2 object2;
    ...
}

@Service
@Transactional
public class Class2{
   ...
}
Run Code Online (Sandbox Code Playgroud)

问题是我需要Class2实现一个接口,所以我只改变了Class2,所以它现在就像:

@Controller
public class Class1 {
    @Autowired
    private Class2 object2;
    ...
}

@Service
@Transactional
public class Class2 implements IServiceReference<Class3, Long>{
   ...
}

public interface IServiceReference<T, PK extends Serializable> {
    public T reference(PK id);
}
Run Code Online (Sandbox Code Playgroud)

用这个代码我得到了一个org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type for Class2.似乎@Transitional注释与接口不兼容,因为如果我删除@Transitional注释或者mplements IServiceReference<Class3, Long>问题消失了并且注入了bean(尽管我需要在这个类中都有).如果我将注释@Transitional放在方法而不是类中,也会发生这种情况.

如果这有帮助,我使用Spring 3.0.2.

与事务方法的接口不兼容?可能是一个Spring bug?

Ada*_*ent 28

问题是你的Class1需要引用IServiceReference而不是Class2的具体引用

@Controller
public class Class1 {
@Autowired
private IServiceReference object2;
    ...
}
Run Code Online (Sandbox Code Playgroud)

这是因为Spring正在为您标记为@Transactional的类创建动态代理.因此,当创建Class2时,它包装在一个Proxy对象中,该对象显然不是Class2类型,但是类型为IServiceReference.

如果您希望使用具有代理支持的Class2的行为,则必须打开以下CGLIB:

来自Springs Doc:

Spring AOP默认使用AOP代理的标准J2SE动态代理.这使得任何接口(或接口集)都可以被代理.

Spring AOP也可以使用CGLIB代理.这是代理类而不是接口所必需的.如果业务对象未实现接口,则默认使用CGLIB.由于编程接口而不是类是一种好的做法,业务类通常会实现一个或多个业务接口.可以强制使用CGLIB,在那些需要建议未在接口上声明的方法,或者需要将代理对象作为具体类型传递给方法的情况下(希望很少见).

掌握Spring AOP是基于代理的这一事实非常重要.请参阅第6.6.1节"了解AOP代理"一节,以全面了解此实现细节的实际含义.


ska*_*man 13

Transactional注释指导春季产生围绕注解的bean代理对象,实现事务语义.生成的代理将实现与目标bean相同的接口.因此,如果您的目标bean实现IServiceReference,那么生成的代理也将如此.

如果目标bean没有实现的接口,那么生成的代理将成为目标bean类型的类.

在您的原始示例中,事务代理将是其子类Class2,因为Class2没有实现接口.当您更改Class2为实现时IServiceReference,生成的代理不再扩展Class2,而是实现IServiceReference.这引起了你ClassCastException.

这种情况最好的办法是从删除提及Class1Class2,而是去跟Class2通过其接口纯粹.Class2可以实现任意数量的接口,代理将实现所有这些接口.

无论接口如何,您都可以强制Spring生成子类代理,但这是额外的复杂性,我建议不要使用它.

  • 基本上我说的一样:) (5认同)