單例模式&CGLIB代理
阿新 • • 發佈:2018-08-20
圖片 instance 攔截 hash odi .net 參考 alt ros
面向大海,春暖花開
來自網友的解析:
Enhancer可能是CGLIB中最常用的一個類,和Java1.3動態代理中引入的Proxy類差不多(如果對Proxy不懂,可以參考這裏)。和Proxy不同的是,Enhancer既能夠代理普通的class,也能夠代理接口。Enhancer創建一個被代理對象的子類並且攔截所有的方法調用(包括從Object中繼承的toString和hashCode方法)。Enhancer不能夠攔截final方法,例如Object.getClass()方法,這是由於Java final方法語義決定的。基於同樣的道理,Enhancer也不能對fianl類進行代理操作。這也是Hibernate為什麽不能持久化final class的原因
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.apache.log4j.Logger;
import java.lang.reflect.Method;
import java.util.Map;
/**
* 代理打印日誌,並生檢查登錄,使用的原則是,name必須要放到第一個參數
* @author Binglong
* @date 2018-03-20
*/
public class RemoteServiceProxy{
private static final Logger logger = Logger.getLogger(RemoteServiceProxy.class);
private static class SingleInstance{
private static final RemoteService INSTANCE = new RemoteServiceProxy().getProxy();
}
/**
* 獲取代理對象的單例
* @return
*/
public static RemoteService getProxyInstance(){
return SingleInstance.INSTANCE;
}
/**
* 獲取代理對象
* @return
*/
public RemoteService getProxy(){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(RemoteService.class);
enhancer.setCallback(getMethodInterceptor());
return (RemoteService)enhancer.create();
}
/**
* SmcName必須要放到第一個參數
* @return
*/
public MethodInterceptor getMethodInterceptor(){
return new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
String smcName = (String) objects[0];
boolean flag = checkLogin(method.getName(), smcName);
if (flag){
//執行父類的方法,也就是RemoteService中的方法
return methodProxy.invokeSuper(o, objects);
}
return null;
}
};
}
/**
* 檢查登錄狀態
* @param methodName
* @param name
* @return
*/
private boolean checkLogin(String methodName, String name){
String logMsg = ‘[‘ + name + "][RemoteServiceProxy." + methodName + ‘]‘;
if (logger.isDebugEnabled()) {
logger.debug(logMsg + " begin...");
}
boolean loginFlag = RemoteService.getInstance().isLogined(name);
if (!loginFlag) {
logger.info(logMsg + " not login, login first");
Map<String, String> header = SmcService.getInstance().header;
loginFlag = RemoteService.getInstance().login(header, name);
if (!loginFlag){
logger.warn(logMsg + " login failed");
return false;
}
}
return true;
}
}
單例模式&CGLIB代理