定义
- 让代理负责完成工作,在必要的时候生成实例(实际主体)。
- 增强被代理对象的功能。
使用场景
- 只有真正需要生成实例的时候,才生成和初始化实例。
- 实现对功能的增强(比如Spring 中的AOP)。
UML图![在这里插入图片描述](https://img-blog.csdnimg.cn/2019091516204738.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0Rhc29uX3l1,size_16,color_FFFFFF,t_70)
三种方式
- 静态代理
– 特点:代理对象和目标对象实现同一接口。
– 优点:不修改目标对象的情况下,能够使用代理对象对功能进行扩展。
– 缺点:代理对象和实际主体都需要实现同一个接口,当接口增加功能,两者都需要维护。 - 动态代理
– 特点:代理对象无需实现接口,动态创建代理对象;目标对象必须实现接口。
– 优点:代理对象无需实现接口,在需要的时候来动态的生成代理对象,从而对功能进行加强。
– 缺点:被代理的对象必须是一个接口类型,否则无法生成代理对象。 - cglib动态代理
– 特点:目标对象无需实现接口。
– 优点:被代理对象无需实现任何接口。方式是构建目标对象的一个子类,从而实现对功能的扩展。
– 缺点:被代理的类不能被final 修饰。
代码实现
public interface ITeacher {
public void teach();
}
public class Teacher implements ITeacher {
@Override
public void teach() {
System.out.println("老师在授课中");
}
}
public class TeacherProxy implements ITeacher {
private ITeacher teacher;
public TeacherProxy(ITeacher teacher){
this.teacher = teacher;
}
@Override
public void teach() {
before();
teacher.teach();
}
public void before(){
System.out.println("准备材料");
}
}
public class Client {
public static void main(String[] args) {
Teacher teacher = new Teacher();
TeacherProxy proxy = new TeacherProxy(teacher);
proxy.teach();
}
}
public interface ITeacher {
public void teach();
}
public class Teacher implements ITeacher {
@Override
public void teach() {
System.out.println("老师在授课中");
}
}
public class ProxyFactory {
public Object getProxy(ITeacher teacher){
InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object o = method.invoke(teacher, args);
return o;
}
};
return Proxy.newProxyInstance(teacher.getClass().getClassLoader(),
teacher.getClass().getInterfaces(), invocationHandler);
}
public void before(){
System.out.println("准备材料");
}
}
public class Client {
public static void main(String[] args) {
ITeacher teacher = new Teacher();
ProxyFactory proxyFactory = new ProxyFactory();
ITeacher proxy = (ITeacher) proxyFactory.getProxy(teacher);
proxy.teach();
}
}
public class Teacher {
public void teach() {
System.out.println("老师在授课中");
}
}
public class CglibProxyFactory<T> implements MethodInterceptor {
private T t;
public CglibProxyFactory(T t) {
this.t = t;
}
public Object getProxy(){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(t.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("方法执行前");
Object value = method.invoke(t, args);
System.out.println("方法执行前后");
return value;
}
}
public class Client {
public static void main(String[] args) {
CglibProxyFactory<Teacher> proxyFactory = new CglibProxyFactory<Teacher>(new Teacher());
Teacher proxy = (Teacher) proxyFactory.getProxy();
System.out.println(proxy);
proxy.teach();
}
}
总结
- 让代理负责完成工作,在必要的时候生成目标实例。
- 通过代理来实现对功能的增强。
- 从静态代理-动态代理-cglib代理,其实就是一个优化的过程,提高代码扩展性和适用性。