在Java开发的时候,经常会使用LocalCache来加快方法的执行时间,
但是在对外暴露方法的时候, LocalCacheData 被调用开发者莫名的Modify , 导致程序出现问题.
下面介绍下如何设计确保LocalCacheData不被修改
有如下两种方式结合使用
ImmutableBean
保证单个bean对象不被修改
包名 org.springframework.cglib.beans.ImmutableBean
Collections.unmodifiableXXX
保证集合对象不被修改
包名 java.util.Collections
单个bean对象
LocalCache Class
@Data
public class UserProfile {
private String no;
private String nickname;
private List<String> hobbies;
}
CacheUtils
public static class CacheUtils {
//----初始化数据----
private static UserProfile userProfile;
static {
UserProfile profile = new UserProfile();
profile.setNo("1");
profile.setNickname("zs");
profile.setHobbies(Lists.newArrayList("Java","Go"));
// 包装成不可变对象
userProfile = (UserProfile) ImmutableBean.create(profile);
}
//----初始化数据----
public static UserProfile getUserProfile(){
return userProfile;
}
}
Junit Test
@Test
public void object(){
UserProfile userProfile = CacheUtils.getUserProfile();
System.out.println(userProfile);
/*
userProfile.setNickname("marion");
System.out.println(userProfile);
*/
//上述方法执行会报错 java.lang.IllegalStateException: Bean is immutable
/*
userProfile.getHobbies().add("Python");
System.out.println(userProfile);
*/
//上述方法执行会成功 UserProfile(no=1, nickname=zs, hobbies=[Java, Go, Python])
//解决办法参考下文 "集合对象"
}
总结:
- 保证单个bean对象不被外部程序修改
- 不保证集合对象的修改操作
集合对象
CacheUtils
public static class CacheUtils {
//----初始化数据----
static Map<String, UserProfile> userProfileMap;
static {
Map<String,UserProfile> map = new HashMap<>(3);
for (int i = 0; i < 3; i++) {
UserProfile profile = new UserProfile();
profile.setNo(""+(i+1));
profile.setNickname("nn_"+(i+1));
// 包装成不可变对象
UserProfile userProfile = (UserProfile) ImmutableBean.create(profile);
map.put(userProfile.getNo(),userProfile);
}
userProfileMap = Collections.unmodifiableMap(map);
}
//----初始化数据----
public static Map<String, UserProfile> getUserProfiles(){
return userProfileMap;
}
}
Junit Test
```java
@Test
public void collection(){
Map<String, UserProfile> userProfiles = CacheUtils.getUserProfiles();
userProfiles.forEach((k,v)->{System.out.println(k+" , "+v);
});
/*
userProfiles.remove("1");
*/
//上述方法执行会报错 java.lang.UnsupportedOperationException, at java.util.Collections$UnmodifiableMap.remove(Collections.java:1460)
/*
UserProfile profile = new UserProfile();
profile.setNo("444");
profile.setNickname("nn_444");
userProfiles.put("444",profile);
*/
//上述方法执行会报错 java.lang.UnsupportedOperationException , at java.util.Collections$UnmodifiableMap.put(Collections.java:1457)
/*
UserProfile profile = userProfiles.get("1");
profile.setNickname("marion");
*/
//上述方法执行会报错 java.lang.IllegalStateException: Bean is immutable
}
> 要保证 **UserProfile.hobbies** 不被修改,需要在初始化缓存的时候设置
>
>
profile.setHobbies(Collections.unmodifiableList(Lists.newArrayList(“Java”,”Go”)));
```
总结
- 如果我们设计的 cache 数据有集合和对象, 可以将 上述两种方式结合使用