Java 用于防止对缓存对象进行setter调用的代理和装饰器
我一直在试图找出如何使用Javassist中的代理来防止对缓存中的任何对象调用setter。缺点是,在curretn应用程序中,缓存中存储的许多对象没有接口,我们需要一个解决方案来防止客户端更改缓存对象值。这是我尝试过的解决方案。你觉得怎么样Java 用于防止对缓存对象进行setter调用的代理和装饰器,java,proxy,Java,Proxy,我一直在试图找出如何使用Javassist中的代理来防止对缓存中的任何对象调用setter。缺点是,在curretn应用程序中,缓存中存储的许多对象没有接口,我们需要一个解决方案来防止客户端更改缓存对象值。这是我尝试过的解决方案。你觉得怎么样 package jp.proof.proxy; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import javassist.
package jp.proof.proxy;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javassist.util.proxy.MethodHandler;
import javassist.util.proxy.Proxy;
import javassist.util.proxy.ProxyFactory;
public class Immutator {
private static class Decorator<O extends Object> implements MethodHandler{
private O o;
private Decorator(O o) {
this.o=o;
}
private Object invoke(O self, Method methodCall, Object[] args) throws Throwable {
System.out.println("Method call: "+methodCall.getName());
if(methodCall.getName().startsWith("set")) {
throw new RuntimeException("Setter is not available");
}
return methodCall.invoke(o, args);
}
@Override
public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable {
return this.invoke((O) self, thisMethod, args);
}
}
public static <O extends Object> O immutateProxy(final O o) throws NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
ProxyFactory f = new ProxyFactory();
f.setSuperclass(o.getClass());
Class c = f.createClass();
Decorator<O> mi = new Decorator<O>(o);
O foo = (O)c.newInstance();
((Proxy)foo).setHandler(mi);
return foo;
}
}
包jp.proof.proxy;
导入java.lang.reflect.InvocationTargetException;
导入java.lang.reflect.Method;
导入javassist.util.proxy.MethodHandler;
导入javassist.util.proxy.proxy;
导入javassist.util.proxy.ProxyFactory;
公共类免疫调节器{
私有静态类装饰器实现MethodHandler{
私人办公室;
私人装修师(O){
这个。o=o;
}
私有对象调用(O self,methodCall,Object[]args)抛出Throwable{
System.out.println(“方法调用:”+methodCall.getName());
if(methodCall.getName().startsWith(“set”)){
抛出新的运行时异常(“Setter不可用”);
}
returnmethodcall.invoke(o,args);
}
@凌驾
公共对象调用(对象自身、方法thisMethod、方法继续、对象[]args)抛出Throwable{
返回this.invoke((O)self,thisMethod,args);
}
}
公共静态O immutateProxy(最终O O)抛出NoSuchMethodException、IllegalArgumentException、InstanceionException、IllegalAccessException、InvocationTargetException{
ProxyFactory f=新的ProxyFactory();
f、 setSuperclass(o.getClass());
类c=f.createClass();
装饰器mi=新装饰器(o);
O foo=(O)c.newInstance();
((代理)foo.setHandler(mi);
返回foo;
}
}
以下是使用Immutator代理其持有的每个实例的缓存:
包jp.proof.proxy
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.collections4.MapUtils;
public class SimpleCache {
private Map<String,UserVo> users;
private static SimpleCache instance;
private SimpleCache() throws Exception {
users=MapUtils.synchronizedMap(new HashMap<>());
users.put("Jonathan",Immutator.immutateProxy(new UserVo("Jonathan","Doe")));
users.put("Alexandre",Immutator.immutateProxy(new UserVo("Alexandre","Doe1")));
users.put("Manille",Immutator.immutateProxy(new UserVo("Manille","Doe2")));
users.put("Jules",Immutator.immutateProxy(new UserVo("Jules","Doe3")));
users.put("Victor",Immutator.immutateProxy(new UserVo("Victor","Doe4")));
}
public static SimpleCache getInstance(){
if(instance==null) {
try {
instance=new SimpleCache();
} catch (Exception e) {
e.printStackTrace();
}
}
return instance;
}
public UserVo getUser(String name){
return users.get(name);
}
}
import java.util.HashMap;
导入java.util.Map;
导入org.apache.commons.collections4.MapUtils;
公共类SimpleCache{
私人地图用户;
私有静态SimpleCache实例;
私有SimpleCache()引发异常{
users=MapUtils.synchronizedMap(新的HashMap());
users.put(“Jonathan”,Immutator.immutateProxy(新UserVo(“Jonathan”,“Doe”));
users.put(“Alexandre”,Immutator.immutateProxy(新的UserVo(“Alexandre”,“Doe1”));
users.put(“Manille”,Immutator.immutateProxy(新的UserVo(“Manille”,“Doe2”));
users.put(“Jules”,Immutator.immutateProxy(新的UserVo(“Jules”,“Doe3”));
users.put(“Victor”,Immutator.immutateProxy(新用户VO(“Victor”,“Doe4”));
}
公共静态SimpleCache getInstance(){
if(实例==null){
试一试{
实例=新的SimpleCache();
}捕获(例外e){
e、 printStackTrace();
}
}
返回实例;
}
public UserVo getUser(字符串名称){
返回users.get(name);
}
}
提前感谢您的评论更新我已经在WebSphere环境(10个耳朵+负载平衡)中使用了大约一周,没有任何性能或内存问题。更新我已经在WebSphere环境(10个耳朵+负载平衡)中使用了大约一周,没有任何性能或内存问题。