加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – @Cacheable打破了DependencyInjection

发布时间:2020-12-14 16:44:43 所属栏目:Java 来源:网络整理
导读:我偶然发现了一个案例,其中使用@Cacheable创建的AOP代理在 Spring 3.1.1中打破了依赖注入.这是我的场景: 我有一个接口和一个在实现的方法中使用@Cacheable实现此接口的类. 示例界面: public interface ImgService { public byte[] getImage(String name);}
我偶然发现了一个案例,其中使用@Cacheable创建的AOP代理在 Spring 3.1.1中打破了依赖注入.这是我的场景:

我有一个接口和一个在实现的方法中使用@Cacheable实现此接口的类.

示例界面:

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测试类 – 一个注入接口,另一个注入实现:

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

接口的依赖注入工作正常.但是,当我在第二个测试类中注入实现时,我得到“注入自动连接的依赖项失败”.我能够调试它,看起来ClassUtils.isAssignableValue()错误地将所需类型与代理类进行比较.它由DefaultListableBeanFactory调用.更奇怪的是,如果我从已实现的方法中删除@Cacheable注释并将其添加到其他一些受保护/私有方法,依赖注入再次正常工作.这是一个错误,处理这种情况的正确方法是什么?

解决方法

这不是一个错误,这是使用JDK动态代理进行AOP实现的预期副作用.

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

当您将@Cacheable移动到private或protected方法时,注入有效,因为@Cacheable在这种情况下不会生效 – 只能使用基于代理的AOP建议公共方法.

因此,您应该声明要作为ImgService注入的字段,或者使用proxy-target-class =“true”将Spring配置为使用基于目标类的代理.

另一种选择是将Spring配置为使用AspectJ-based AOP implementation(需要编译时或加载时编织).

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

也可以看看:

> 7.6 Proxying mechanisms

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读