设计模式-代理模式
面向大海,春暖花开
来自网友的解析:
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;
}
}