@Autowire奇怪的问题 [英] @Autowire strange problem

查看:126
本文介绍了@Autowire奇怪的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a strange behaviour when autowiring

我有类似这样的代码,它可以工作

I have a similar code like this one, and it works

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

@Service
@Transactional
public class Class2{
   ...
}

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

The problem is that I need that the Class2 implements an interface so I've only changed the Class2 so it's now like:

@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);
}

使用此代码我得到 org.springframework。 beans.factory.NoSuchBeanDefinitionException:Class2的类型没有匹配的bean
似乎 @Transitional 注释与界面不兼容,因为如果我删除 @Transitional 注释或者i 实现IServiceReference< Class3,Long> 问题消失并注入bean(尽管我需要在这个类中都有)。如果我在方法中而不是在类中放置注释 @Transitional ,也会发生这种情况。

with this code I get a org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type for Class2. It seems that @Transitional annotation is not compatible with the interface because if I remove the @Transitional annotation or the implements IServiceReference<Class3, Long> the problem disapears and the bean is injected (though I need to have both in this class). It also happens if I put the annotation @Transitional in the methods instead of in the Class.

我使用Spring 3.0.2如果这有帮助。

I use Spring 3.0.2 if this helps.

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

Is not compatible the interface with the transactional method? May it be a Spring bug?

推荐答案

问题是你的Class1需要一个对IServiceReference的引用,而不是Class2的具体参考

The problem is that your Class1 needs a reference to IServiceReference and not the concrete reference of Class2

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

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

The reason this is that Spring is creating a dynamic proxy for classes that you marked @Transactional. Thus when Class2 is created its wrapped in a Proxy object that is obviously not of type Class2 but is of type IServiceReference.

如果你想要使用带有代理支持的Class2的行为你必须打开CGLIB
阅读以下内容:

If you want the behavior of using Class2 with proxy support you will have to turn on CGLIB Read below:

来自Springs Doc:

From Springs Doc:


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

Spring AOP defaults to using standard J2SE dynamic proxies for AOP proxies. This enables any interface (or set of interfaces) to be proxied.

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

Spring AOP can also use CGLIB proxies. This is necessary to proxy classes, rather than interfaces. CGLIB is used by default if a business object does not implement an interface. As it is good practice to program to interfaces rather than classes, business classes normally will implement one or more business interfaces. It is possible to force the use of CGLIB, in those (hopefully rare) cases where you need to advise a method that is not declared on an interface, or where you need to pass a proxied object to a method as a concrete type.

重要的是要掌握
这一事实Spring AOP是基于代理的。请参阅
部分标题为第6.6.1节,
理解AOP代理,以便
彻底检查这个实现细节究竟是什么
实际上是
的意思。

It is important to grasp the fact that Spring AOP is proxy-based. See the section entitled Section 6.6.1, "Understanding AOP proxies" for a thorough examination of exactly what this implementation detail actually means.

这篇关于@Autowire奇怪的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆