gpt4 book ai didi

java - @Cacheable 打破 DependencyInjection

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:51:14 27 4
gpt4 key购买 nike

在Spring 3.1.1中偶然发现使用@Cacheable创建的AOP代理破坏依赖注入(inject)的情况。这是我的场景:

我有一个接口(interface)和一个在实现的方法中使用@Cacheable 实现这个接口(interface)的类。

示例界面:

public interface ImgService {
public byte[] getImage(String name);
}

示例实现:

public class ImgServiceImpl implements ImgService {

@Cacheable(cacheName = "someCache")
public byte[] getImage(String name){//TODO};

protected String someOtherMethod(){//};
}

我还必须测试 JUnit 类 - 一个注入(inject)接口(interface),一个注入(inject)实现:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:META-INF/spring.xml" })
public class ImgServiceTest {

@Inject
private ImgService;
}

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:META-INF/spring.xml" })
public class ImgServiceImplTest {

@Inject
private ImgServiceImpl;
}

接口(interface)的依赖注入(inject)工作正常。然而,当我开始在第二个测试类中注入(inject)实现时,我得到了一个“注入(inject) Autowiring 的依赖项失败”。我能够对其进行调试,并且 ClassUtils.isAssignableValue() 似乎错误地将所需类型与代理类进行了比较。它由 DefaultListableBeanFactory 调用。更奇怪的是,如果我从实现的方法中删除 @Cacheable 注释并将其添加到其他一些 protected /私有(private)方法中,依赖注入(inject)将再次正常工作。这是一个错误吗?处理这种情况的正确方法是什么?

最佳答案

这不是错误,这是使用 JDK 动态代理实现 AOP 的预期副作用。

由于对 ImgServiceImpl 的可缓存方法的所有调用都应该通过 ImgService 类型的动态代理,因此无法将此依赖项注入(inject)到 类型的字段中code>ImgServiceImpl.

当您将 @Cacheable 移动到 privateprotected 方法时,注入(inject)会起作用,因为 @Cacheable 不会在这种情况下生效 - 只有 public 方法可以使用基于代理的 AOP 建议。

因此,您应该将要注入(inject)的字段声明为 ImgService,或者将 Spring 配置为使用基于目标类的代理,而不是使用 proxy-target-class = "true".

另一个选择是配置 Spring 使用 AspectJ-based AOP implementation (需要编译时或加载时织入)。

它适用于 Spring 提供的所有基于 AOP 的特性(事务、安全性、异步执行、缓存、自定义方面等)。

另请参阅:

关于java - @Cacheable 打破 DependencyInjection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11937354/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com