- 定义:给目标对象一个代理对象,并由代理对象控制对目标对象的引用;
- 实质:代理并不是新技术,而是一种设计模式;通过代理对象间接的访问目标对象,防止直接访问目标对象给系统带来的不必要复杂度;
- 优点:可以在实现目标代码的基础上,增强额外的功能,即扩展目标对象的功能。如果需要改代码,不需要对源代码进行修改,仅需要修改代理代码;
- 作用:增强;
- 特点:代理对象控制的范围(或者说其功能强度)是要大于目标对象的,是在目标对象的基础上的扩展。
public interface ByClothes {
void clothes(String size);
}
(二)有了接口就需要去实现,写一个实现类
public class ClothesFactory implements ByClothes{
@Override
public void clothes(String size) {
// TODO Auto-generated method stub
System.out.println("为您制作了一套size为"+size+"的衣服");
}
}
(三)写一个代理类,在实现类的基础上进行增强
public class ProxyClothes implements ByClothes{
// 代理需要联系工厂,即实现类
public ClothesFactory factory;
// 写一个构造方法,接收参数
public ProxyClothes(ClothesFactory factory) {//该处的参数列表是写死的
// TODO Auto-generated constructor stub
this.factory=factory;
}
// 重写时,进行增强
@Override
public void clothes(String size) {
// TODO Auto-generated method stub
frontService();
factory.clothes(size);
endService();
}
public void frontService() {
System.out.println("为您提供售前服务");
}
public void endService() {
System.out.println("为您提供售后服务");
}
}
主方法
public class Test{
public static void main(String[] args) {
ClothesFactory factory = new ClothesFactory();
ProxyClothes p = new ProxyClothes(factory);//代理对接目标工厂,创建对象
p.clothes("XXL");//调用代理重写的方法
System.out.println("===========");
factory.clothes("XL");//如果不使用代理,直接调用工厂的方法,少一个增强
}
}
二、动态代理(基于jdk)
该动态代理的思路可以依照静态代理展开,但是在该代理对应的工厂并不是写死的,是动态的。这就需要用到反射。
可以把代理类理解为一个代理公司// 需要使用InvocationHandler(调用处理器)接口,对接口中的方法重写时,进行增强
public class ProxyCompany implements InvocationHandler{
//被代理的对象,这里其类型并不确定
private Object factory;
public Object getFactory() {
return factory;
}
public void setFactory(Object factory) {
this.factory = factory;
}
//代理类要完成的功能,要写在这个invoke()方法中
//1、目标方法调用
//2、功能增强
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//Object proxy:jdk创建的代理对象
//Method method 目标类中的方法,jdk提供method对象,这个方法是,
//cobject.clothes("XXL"); 之后,进入该方法,同时把method传了过来
// TODO Auto-generated method stub
frontService();
method.invoke(factory, args);//方法调用(反射)
endService();
return null;
}
public void frontService() {
System.out.println("为您提供售前服务");
}
public void endService() {
System.out.println("为您提供售后服务");
}
//创建员工,代理实例化
public Object getProxyInstance() {
//Proxy自带的方法,创建代理实例
//第一次参数 类加载器
//第二个参数 接口,确定哪个工厂后,接口也就确定了
//this 当前getProxyInstance方法
return Proxy.newProxyInstance(factory.getClass().getClassLoader(), factory.getClass().getInterfaces(), this);
}
}
主方法
public class Test{
public static void main(String[] args) {
ClothesFactory clothesFactory = new ClothesFactory();
ProxyCompany proxyCompany = new ProxyCompany();
//衣服
proxyCompany.setFactory(clothesFactory);//告诉代理是哪个工厂
//调用公司的创建员工方法,但是代理内部并没有这个具体的方法,所以需要ByClothes
ByClothes cobject = (ByClothes)proxyCompany.getProxyInstance();
cobject.clothes("XXL");
}
}
三、动态代理(基于CGLIB)


