首页 > 编程知识 正文

springmvc常用注解有哪些,spring 自定义注解

时间:2023-05-04 11:14:12 阅读:17542 作者:4904

关于注释redis和Spring Cache的集成,请参考上一章

@Cacheable @Cacheable的作用主要针对方法配置,可以根据方法的请求参数缓存其结果

@Cacheable角色和配置方法参数说明了examplevalue缓存的名称,并在spring配置文件中定义,必须至少指定一个,例如:

@cacheable(value=”mycache”)

@cacheable(value={”cache1”、“cache2”}

key缓存中的key可以是空的。 如果指定或不指定根据SpEL表达式编写,则缺省情况下根据方法的所有参数进行@cacheable(value=) testcache ()、key=) (username ) ) condition 可以是空的@cacheable(value=”testcache”,condition=”#userName.length )”)实例@cacheable 如果不存在,则运行实际方法(即查询数据库),并将执行的结果保存到缓存中。 否则,返回缓存中的对象。 此处缓存中的key是参数userName,value是帐户对象。 帐户缓存是在spring*.xml中定义的名称。

@cacheable(value='accountcache ' )/accountcachepublicaccountgetaccountbyname ) /方法内部实现不考虑缓存逻辑的returngetfromdb } @CachePut @CachePut的作用主要针对方法配置,可以根据方法的请求参数缓存其结果,但与@Cacheable不同,每次都会触发实际方法的调用

@CachePut的角色和配置参数解释examplevalue缓存的名称,并在spring配置文件中定义。 @cacheput(value="mycache " )密钥缓存必须至少指定一个密钥。 如果不指定,则可以为空。 如果按照SpEL表达式编写,则默认情况下,@cacheput(value=”testcache”, key=”#userName”) )在方法的所有参数中组合condition缓存的条件可以是空的,用SpEL编写,返回true或false,只在true时缓存@ cocodition缓存此注释确保方法运行,同时方法的返回值也记录在缓存中,以便缓存和数据库同步更新。

@cacheput(value='accountcache ',key='#account.getName ) ) accountCache缓存公共缓存访问

@CacheEvict角色和配置参数解释examplevalue缓存的名称,并在spring配置文件中定义。 @cacheevict(value="mycache " )密钥缓存必须至少指定一个密钥。 如果不指定,则可以为空。 必须按照SpEL表达式编写(缺省情况下,@cacheevict(value=”testcache”,key=”#userName”) )缓存,该缓存由方法的所有参数组成只为true缓存的@cacheevict(value=”testcache”,condition=”#userName.length”) allEntries是否清空所有缓存,请参见如果指定为true,则为true。调用方法时,所有缓存立即为空@cachevict(value=”testcache”,allEntries=true ) beforeInvocation为如果指定为true,则在方法尚未执行时清空缓存@cachevict(value=“testcache”,beforeInvocation=true )实例@ cache evicion

unt(Account account) { updateDB(account); } @CacheEvict(value="accountCache",allEntries=true)// 清空accountCache 缓存public void reload() { reloadAll()}@Cacheable(value="accountCache",condition="#userName.length() <=4")// 缓存名叫 accountCache public Account getAccountByName(String userName) { // 方法内部实现不考虑缓存逻辑,直接实现业务 return getFromDB(userName); } @CacheConfig

所有的@Cacheable()里面都有一个value=“xxx”的属性,这显然如果方法多了,写起来也是挺累的,如果可以一次性声明完 那就省事了,
所以,有了@CacheConfig这个配置,@CacheConfig is a class-level annotation that allows to share the cache names,如果你在你的方法写别的名字,那么依然以方法的名字为准。

@CacheConfig("books")public class BookRepositoryImpl implements BookRepository { @Cacheable public Book findBook(ISBN isbn) {...}} 条件缓存

下面提供一些常用的条件缓存

//@Cacheable将在执行方法之前( #result还拿不到返回值)判断condition,如果返回true,则查缓存; @Cacheable(value = "user", key = "#id", condition = "#id lt 10")public User conditionFindById(final Long id) //@CachePut将在执行完方法后(#result就能拿到返回值了)判断condition,如果返回true,则放入缓存; @CachePut(value = "user", key = "#id", condition = "#result.username ne 'zhang'") public User conditionSave(final User user) //@CachePut将在执行完方法后(#result就能拿到返回值了)判断unless,如果返回false,则放入缓存;(即跟condition相反)@CachePut(value = "user", key = "#user.id", unless = "#result.username eq 'zhang'")public User conditionSave2(final User user) //@CacheEvict, beforeInvocation=false表示在方法执行之后调用(#result能拿到返回值了);且判断condition,如果返回true,则移除缓存;@CacheEvict(value = "user", key = "#user.id", beforeInvocation = false, condition = "#result.username ne 'zhang'") public User conditionDelete(final User user) @Caching

有时候我们可能组合多个Cache注解使用;比如用户新增成功后,我们要添加id–>user;username—>user;email—>user的缓存;此时就需要@Caching组合多个注解标签了。

@Caching(put = {@CachePut(value = "user", key = "#user.id"),@CachePut(value = "user", key = "#user.username"),@CachePut(value = "user", key = "#user.email")})public User save(User user) { 自定义缓存注解

比如之前的那个@Caching组合,会让方法上的注解显得整个代码比较乱,此时可以使用自定义注解把这些注解组合到一个注解中,如:

@Caching(put = {@CachePut(value = "user", key = "#user.id"),@CachePut(value = "user", key = "#user.username"),@CachePut(value = "user", key = "#user.email")})@Target({ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Inheritedpublic @interface UserSaveCache {}

这样我们在方法上使用如下代码即可,整个代码显得比较干净。

@UserSaveCachepublic User save(User user) 扩展

比如findByUsername时,不应该只放username–>user,应该连同id—>user和email—>user一起放入;这样下次如果按照id查找直接从缓存中就命中了

@Caching( cacheable = { @Cacheable(value = "user", key = "#username") }, put = { @CachePut(value = "user", key = "#result.id", condition = "#result != null"), @CachePut(value = "user", key = "#result.email", condition = "#result != null") })public User findByUsername(final String username) { System.out.println("cache miss, invoke find by username, username:" + username); for (User user : users) { if (user.getUsername().equals(username)) { return user; } } return null;}

其实对于:id—>user;username—->user;email—>user;更好的方式可能是:id—>user;username—>id;email—>id;保证user只存一份;如:

@CachePut(value="cacheName", key="#user.username", cacheValue="#user.username") public void save(User user) @Cacheable(value="cacheName", key="#user.username", cacheValue="#caches[0].get(#caches[0].get(#username).get())") public User findByUsername(String username) SpEL上下文数据

Spring Cache提供了一些供我们使用的SpEL上下文数据,下表直接摘自Spring官方文档:

名称位置描述示例methodNameroot对象当前被调用的方法名root.methodNamemethodroot对象当前被调用的方法root.method.nametargetroot对象当前被调用的目标对象root.targettargetClassroot对象当前被调用的目标对象类root.targetClassargsroot对象当前被调用的方法的参数列表root.args[0]cachesroot对象当前方法调用使用的缓存列表(如@Cacheable(value={“cache1”, “cache2”})),则有两个cacheroot.caches[0].nameargument name执行上下文当前被调用的方法的参数,如findById(Long id),我们可以通过#id拿到参数user.idresult执行上下文方法执行后的返回值(仅当方法执行之后的判断有效,如‘unless’,’cache evict’的beforeInvocation=false)result @CacheEvict(value = "user", key = "#user.id", condition = "#root.target.canCache() and #root.caches[0].get(#user.id).get().username ne #user.username", beforeInvocation = true) public void conditionUpdate(User user)

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。