1. 代理模式: 为一个对象提供一个替身,以控制对这个对象的访问,即通过代理对象访问目标对象,这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。
2. 被代理的对象可以是远程对象,创建开销大的对象或需要安全控制的对象。
3. 代理模式有不同的形式,主要有三种: 静态代理,动态代理(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 target){
super();
this.target = target;
}
@Override
public void teach() {
System.out.println("事务开始...");
target.teach();
System.out.println("事务结束...");
}
}
public class Client {
public static void main(String[] args){
TeacherDaoProxy proxy = new TeacherDaoProxy(new TeacherDao());
proxy.teach();
}
}
动态代理:
1. 代理对象不需要实现接口, 但是目标对象要实现接口,否则不能用动态代理。
2. 代理对象的生成,是利用jdk的api,动态的在内存中构建代理对象。
public interface ITeacherDao {
void teach();
}
public class TeacherDao implements ITeacherDao{
@Override
public void teach() {
System.out.println("授课中...");
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
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 returnO = method.invoke(target, args);
System.out.println("事务结束...");
return returnO;
}
});
}
}
public class Client {
public static void main(String[] args){
TeacherDao teacherDao = new TeacherDao();
ITeacherDao dProxy = (ITeacherDao)new ProxyFactory(teacherDao).getProxyInstance();
dProxy.teach();
System.out.println(""+dProxy.getClass());
}
}
cglib代理
当目标对象只是一个单独的对象,并没有实现任何的接口,这个时候可使用目标对象子类来实现代理,这就是cglib代理。
cglib包的底层是通过使用字节码处理框架ASM来转换字节码并生成新的类。