一、简介
代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问。即通过代理对象访问目标对象,这样可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。
主要形式有:静态代理、JDK动态代理、Cglib代理。
二、结构
三、静态代理
代理对象和目标对象实现同一接口,并将目标对象封装在代理对象中,通过调用代理对象的方法,从而调用到目标对象的方法。
public interface ITeacherDao {
void teach();
}
public class TeacherDao implements ITeacherDao {
@Override
public void teach() {
System.out.println("老师授课中。。。。");
}
}
public class TeacherDaoProxy implements ITeacherDao {
private ITeacherDao target;
public TeacherDaoProxy(ITeacherDao teacherDao) {
this.target = teacherDao;
}
@Override
public void teach() {
System.out.println("proxy start ....");
target.teach();
System.out.println("proxy end ....");
}
}
四、JDK动态代理
代理对象不需要实现接口,但是目标对象必须实现接口。利用JDK的api,动态在内存中构建代理对象。
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("JDK代理开始...");
Object invoke = method.invoke(target, args);
System.out.println("JDK代理结束...");
return invoke;
}
});
}
}
public class Client {
public static void main(String[] args) {
ITeacherDao teacherDao = new TeacherDao();
ITeacherDao proxyInstance = (ITeacherDao) new ProxyFactory(teacherDao).getProxyInstance();
proxyInstance.teach();
}
}
五、Cglib动态代理
代理对象和目标对象都无需实现接口。在内存中构建一个子类对象从而实现对目标对象功能扩展,底层通过使用字节码处理框架ASM来转化字节码并生成新的类。
public class CglibProxy implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("before...");
Object result = methodProxy.invokeSuper(o, objects);
System.out.println("after...");
return result;
}
}
public class Client {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(TeacherDao.class);
enhancer.setCallback(new CglibProxy());
ITeacherDao teacherDao = (TeacherDao) enhancer.create();
teacherDao.teach();
}
}