单例模式&CGLIB代理

Posted nedhome

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单例模式&CGLIB代理相关的知识,希望对你有一定的参考价值。

面向大海,春暖花开

技术分享图片

 来自网友的解析:

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代理的主要内容,如果未能解决你的问题,请参考以下文章

Spring面试题集锦

Spring面试题集锦

深入理解设计模式-代理模式(静态代理动态代理jdk和cglib)

深入理解设计模式-代理模式(静态代理动态代理jdk和cglib)

代理模式(静态代理jdk动态代理CGLib动态代理)

设计模式3.3-- CGLIB动态代理源码解读