代理模式

静态代理模式

静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象需要一起实现相同的接口或者是继承相同的父类。

案例:教师教书,在teach()方法前后分别做额外的处理

类图如下:

接口:

public interface ITeacherDao {
    public void teach();
}

实现类:

public class TeacherDao implements ITeacherDao {

    @Override
    public void teach() {
        System.out.println("教师教书");
    }
}

代理类:

public class TeacherDaoProxy implements ITeacherDao {

    private ITeacherDao teacherDao;

    public TeacherDaoProxy(ITeacherDao teacherDao) {
        this.teacherDao = teacherDao;
    }

    @Override
    public void teach() {
        System.out.println("前处理");
        teacherDao.teach();
        System.out.println("后处理");
    }
}

客户端测试类:

public class Client {
    public static void main(String[] args) {
        //创建目标对象
        TeacherDao teacherDao = new TeacherDao();

        //创建代理对象
        TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy(teacherDao);

        teacherDaoProxy.teach();
    }
}

缺点:一旦接口中增加方法,目标对象与代理对象都要维护

动态代理

1)在动态代理中,代理对象不需要实现接口,但是目标对象要实现接口,否则不能用动态代理

2)代理对象的生成,利用JDK中的反射机制,动态的在内存中构建代理对象

3)JDK实现代理只需要使用newProxyInstance方法,需要接收三个参数:

ClassLoader、Interfaces 以及InvocationHandler

接口:

public interface ITeacherDao {
    public void teach();
}

实现类:

public class TeacherDao implements ITeacherDao {
    @Override
    public void teach() {
        System.out.println("教师教书中");
    }
}

代理工厂类:

public class ProxyFactory {

    private Object target;

    public ProxyFactory(Object target) {
        this.target = target;
    }

    public Object getProxyInstance(){
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("处理前");
                Object invokeVal = method.invoke(target, args);
                System.out.println("处理后");
                return invokeVal;
            }
        });
    }
}

客户端测试类:

public class Client {
    public static void main(String[] args) {
        //创建目标对象
        ITeacherDao teacherDao = new TeacherDao();

        //创建代理对象
        ProxyFactory proxyFactory = new ProxyFactory(teacherDao);

        ITeacherDao instance = (ITeacherDao) proxyFactory.getProxyInstance();
        instance.teach();
    }
}

代理模式-Cglib

Cglib代理也叫作子类代理,不需要实现某个类。

目标类:

package com.atguigu.proxy.cglib;

public class TeacherDao {

	public void teach() {
		System.out.println(" 老师授课中  , 我是cglib代理,不需要实现接口 ");
	}
}

代理工厂类:

实现MethodInterceptor接口,重写intercept方法

package com.atguigu.proxy.cglib;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class ProxyFactory implements MethodInterceptor {

	//维护一个目标对象
	private Object target;
	
	//构造器,传入一个被代理的对象
	public ProxyFactory(Object target) {
		this.target = target;
	}

	//返回一个代理对象:  是 target 对象的代理对象
	public Object getProxyInstance() {
		//1. 创建一个工具类
		Enhancer enhancer = new Enhancer();
		//2. 设置父类
		enhancer.setSuperclass(target.getClass());
		//3. 设置回调函数
		enhancer.setCallback(this);
		//4. 创建子类对象,即代理对象
		return enhancer.create();
		
	}
	

	//重写  intercept 方法,会调用目标对象的方法
	@Override
	public Object intercept(Object arg0, Method method, Object[] args, MethodProxy arg3) throws Throwable {
		System.out.println("Cglib代理模式 ~~ 开始");
		Object returnVal = method.invoke(target, args);
		System.out.println("Cglib代理模式 ~~ 提交");
		return returnVal;
	}

}

客户端测试类:

package com.atguigu.proxy.dynamic;

public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//创建目标对象
		ITeacherDao target = new TeacherDao();
		
		//给目标对象,创建代理对象, 可以转成 ITeacherDao
		ITeacherDao proxyInstance = (ITeacherDao)new ProxyFactory(target).getProxyInstance();
	
		// proxyInstance=class com.sun.proxy.$Proxy0 内存中动态生成了代理对象
		System.out.println("proxyInstance=" + proxyInstance.getClass());
		
		//通过代理对象,调用目标对象的方法
		//proxyInstance.teach();
		
		proxyInstance.sayHello(" tom ");
	}

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值