在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
@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 数据有集合和对象, 可以将 上述两种方式结合使用