代理模式

代理模式的定义很简单:给某一对象提供一个代理对象,并由代理对象控制对原对象的引用

静态代理

静态代理为业务实现类和业务代理类两部分组成,业务实现类负责实现主要的业务方法,业务代理类负责对调用的业务方法预处理,调用业务时,不是直接通过业务实现类来调用的,而是通过业务代理类的同名方法来调用被代理类处理过的业务方法
public class UserDaoProxy implements IUserDao{
    private IUserDao userDao;
    public UserDaoProxy(IUserDao userDao) {
        this.userDao = userDao;
    }
    
    @Override
    public void save() {
        System.out.println("开启事务");//扩展了额外功能
        userDao.save();
        System.out.println("提交事务");
    }
}

动态代理

在程序运行时运用反射机制动态创建而成

jdk动态代理

只能代理实现了接口的类,代理对象本身并不真正实现服务,而是通过调用委托类的对象相关方法,提供特定服务,通过接口中的方法名,在动态生成的代理类中调用委托实现类的同名方法
定义业务逻辑接口,实现业务逻辑接口创建业务实现类
public class BookFacadeProxy implements InvocationHandler {  
    private Object target;//这其实业务实现类对象,用来调用具体的业务方法 
    /** 
     * 绑定业务对象并返回一个代理类  
     */  
    public Object bind(Object target) {  
        this.target = target;  //接收业务实现类对象参数
       //通过反射机制,创建一个代理类对象实例并返回,用户进行方法调用时使用,创建代理对象时,需要传递该业务类的类加载器、全部的接口、代理类实例
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),  
                target.getClass().getInterfaces(), this); }  
    /** 
     * 包装调用方法:进行预处理、调用后处理 
     */  
    public Object invoke(Object proxy, Method method, Object[] args)  
            throws Throwable {  
        Object result=null;  
        System.out.println("预处理操作——————");  
        //调用真正的业务方法  
        result=method.invoke(target, args);  
        System.out.println("调用后处理——————");  
        return result;  
    }  
} 

cglib动态代理

针对类实现代理,通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑,通过继承业务类,生成的动态代理类是业务类的子类,通过重写业务方法进行代理
public class BookFacadeCglib implements MethodInterceptor {  
    private Object target;//业务类对象,供代理方法中进行真正的业务方法调用
    //相当于JDK动态代理中的绑定
    public Object getInstance(Object target) {  
        this.target = target;  //给业务对象赋值
        Enhancer enhancer = new Enhancer(); //创建加强器,用来创建动态代理类
        enhancer.setSuperclass(this.target.getClass());  //为加强器指定要代理的业务类(即:为下面生成的代理类指定父类)
        //设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方法进行拦截/预处理
        enhancer.setCallback(this); 
       // 创建动态代理类对象并返回  
       return enhancer.create(); 
    }
    // 实现回调方法 
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { 
        System.out.println("预处理——————");
        proxy.invokeSuper(obj, args); //调用业务类(父类中)的方法
        System.out.println("调用后操作——————");
        return null; 
    } 

 

posted @ 2018-09-07 16:11  kangaroohu  阅读(222)  评论(0编辑  收藏  举报