目录
1. 静态代理
2. 动态代理
3. Cglib代理
代理模式:为一个对象提供一个替身,以控制对这个对象的访问。好处就是可以用来增强。
被代理的对象可以是 远程对象,创建开销大的对象 或者 需要安全控制的对象。
可以分为三类
- 静态代理
- 动态代理(JDK代理,接口代理)
- Cglib代理(属于动态代理,在内存动态的创建对象,而不需要实现接口)
示意图

1. 静态代理
目标对象与代理对象都要实现同一个接口或者继承相同父类。

代码实现:
public interface ITeacherDao {
    String teach();
}
public class TeacherDao implements ITeacherDao{
    private String name;
    public TeacherDao(String name) {
        this.name = name;
    }
    @Override
    public String teach() {
        System.out.println(name + "老师正在讲课。。。");
        return name;
    }
}
public class TeacherDaoProxy implements ITeacherDao{
    private ITeacherDao teacherDao;
    public TeacherDaoProxy(ITeacherDao teacherDao) {
        this.teacherDao = teacherDao;
    }
    @Override
    public String teach() {
        System.out.println("开始静态代理。。。,可以进行增强");
        String name = teacherDao.teach();
        System.out.println("结束静态代理。。。");
        return name;
    }
}Client:
public class Client {
    public static void main(String[] args) {
        ITeacherDao target = new TeacherDao("ksj");
        TeacherDaoProxy proxy = new TeacherDaoProxy(target);
        String teach = proxy.teach();
        System.out.println(teach);
    }
} 
2. 动态代理

静态代理缺点:因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类 ,一旦接口增加方法,目标对象与代理对象都要维护。
这就要用到动态代理了,动态的在内存中构建代理对象,只需要目标对象实现接口。利用JDK的Api来实现。
java.lang.reflect.Proxy里面的
newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
- ClassLoader loader:目标对象的类加载器。
- Class<?>[] interfaces: 目标对象实现的接口数组。
- InvocationHandler h:事件处理器,里面利用反射调用方法。
接口和目标类与上面静态代理相同,下面直接写代理工厂类
public class ProxyFactory {
    private final 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("JDK代理开始");
                Object returnVal = method.invoke(target, args);
                System.out.println("JDK代理结束");
                return returnVal;
            }
        });
    }
}public class Client {
    public static void main(String[] args) {
        ITeacherDao target = new TeacherDao("ksj");
        System.out.println("target=" + target.getClass());
        ProxyFactory proxyFactory = new ProxyFactory(target);
        ITeacherDao proxyInstance = (ITeacherDao) proxyFactory.getProxyInstance();
        // proxyInstance=class com.sun.proxy.$Proxy0 内存中动态生成了代理对象
        System.out.println("proxyInstance=" + proxyInstance.getClass());
        String name = proxyInstance.teach();
        System.out.println(name);
    }
}
3. Cglib代理
 Cglib
 代理也叫作子类代理,属于动态代理。相比较静态代理和JDK代理,Cglib代理不需要实现接口。Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接
 口.
 它广泛的被许多
 AOP
 的框架使用
 ,
 例如
 Spring AOP
 ,实现方法拦截。 
 
- 目标对象需要实现接口,用JDK代理
- 目标对象不需要实现接口,用Cglib代理
 
 简单来说就是实现MethodIterceptor接口,实现
 intercept接口来实现代理。
 
代码实现:
public class TeacherDao {
	public String teach() {
		System.out.println(" 老师授课中  , 我是cglib代理,不需要实现接口 ");
		return "hello";
	}
}
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;
	}
}
public class Client {
	public static void main(String[] args) {
		//创建目标对象
		TeacherDao target = new TeacherDao();
		//获取到代理对象,并且将目标对象传递给代理对象
		TeacherDao proxyInstance = (TeacherDao)new ProxyFactory(target).getProxyInstance();
		//执行代理对象的方法,触发intecept 方法,从而实现 对目标对象的调用
		String res = proxyInstance.teach();
		System.out.println("res=" + res);
	}
}还有其他代理变体:
- 防火墙代理
- 缓存代理
- 远程代理
- 同步代理等








![[附源码]SSM计算机毕业设计基于社区生鲜配送系统JAVA](https://img-blog.csdnimg.cn/37fc810373d64b4e84bd8f10018f2977.png)




![[附源码]计算机毕业设计JAVA篮球装备商城系统](https://img-blog.csdnimg.cn/eca4c536b1104aeca9ae2d8939dc3d54.png)





