说我有一个Rest控制器:
@RestController
public class FooController {
/* foobar instantiation/declaration goes here */
@RequestMapping("/foo")
public String bar(@RequestParam(value = "baz") String baz) {
return foobar.createResponse(baz);
}
}
createResponse()
方法带有@Cacheable
注释。
当我像private Foobar foobar = new Foobar();
那样实例化foobar时,缓存不起作用。
但是,当使用@Autowired private Foobar foobar;
之类的东西时,缓存就可以了。
我一直在四处看看,据我所知,Spring在缓存中使用代理类。所以我的问题是,如果没有某种依赖注入,就不能使用缓存吗?是因为Spring必须注入代理类吗? 谢谢!
答案 0 :(得分:1)
所以我的问题是,如果没有某种方式,您是否不能使用缓存 依赖注入
依赖注入不是问题的原因。问题是您想使用Spring功能,但是只要这些功能由Spring管理(通常称为Spring Bean),就能使用所需的特定或横向功能(此处为缓存功能)来使应用程序的对象赋权/丰富化的Spring功能起作用。 。
这对org.springframework.cache.annotation.Cacheable
是正确的,但对于事务,注入,安全性,生成的实现等,也适用于Spring为我们的对象提供的功能。
您必须考虑Spring不会监视JVM中存在的所有对象。这会很复杂,非常慢,而且也不是所希望的,因为并不是所有对象都不是Spring Bean。
如果不想使此类成为bean,请不要将Spring用于缓存功能。例如,单独使用EhCache。但是结果是它只会使您编写更多样板代码。如果使用Spring,那将非常可惜。
答案 1 :(得分:1)
在private Foobar foobar = new Foobar();
中,您正在创建一个新对象,而不是从spring容器中取出一个对象,因此不会进行任何日志记录。
但是当您使用@Autowired private Foobar foobar;
时,要取用由弹簧容器创建的对象,弹簧会将对象注入到该引用中。
答案 2 :(得分:1)
为了回答这个问题,您需要了解spring是如何工作的。 我将尽力提供一个简单的解释,尽管再一次,对spring作为框架的职责的深入了解肯定会在这里为您提供帮助。
启用缓存后,spring有效地将您的对象(在这种情况下为Foo)包装到某种运行时生成的代理中,从而增加了缓存功能。
现在,spring只能对它管理的对象执行此操作。
因此,如果您自己实例化Foo
(Foo foo = new Foo()
)spring实际上已经不在游戏中,spring甚至不知道该对象存在。因此,当然,这里不会创建任何代理。请注意,即使Spring“知道”如何处理类型为Foo
的对象(读取,在应用程序上下文中有类型为Foo
的Bean),它也无法管理这个具体实例
现在,如果您使用自动装配(或一般来说注入依赖项),您会说完全不同的话:
因此,spring现在可以完成工作-缓存工作:)
答案 3 :(得分:1)
使用new运算符创建新对象时,将由您自己实例化该对象,这意味着其生命周期不受Spring管理。
当您创建一个bean并对其进行自动装配时,其实例化将由spring框架进行管理。
在缓存的情况下,当您具有@Cacheable注释时,spring将返回一个代理而不是实际的实例化对象。代理负责缓存结果,并根据您提供的元数据(注释)放入和撤出缓存。