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来转换字节码并生成新的类。