分类和代码示例:
目录
静态代理
动态代理
JDK代理
Cglib代理
JDK代理和Cglib代理的区别
可能会引起类爆炸
类爆炸:类的数量太多引发的问题
//衣服接口
public interface ByClothes {
void clothes(String size);
}
//服装工厂类,具有制作衣服的功能
public class ClothesFactory implements ByClothes{
@Override
public void clothes(String size) {
System.out.println("为您制作了一件大小为"+size+"的衣服");
}
}
//服装工厂代理类
public class ClothesProxy implements ByClothes{
public ClothesFactory factory=new ClothesFactory();
@Override
public void clothes(String size) {
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) {
ClothesProxy proxy=new ClothesProxy();
proxy.clothes("x1");
}
}
执行结果:
售前服务
为您制作了一件大小为x1的衣服
售后服务
基于接口,通过反射
//包包接口
public interface ByBag {
void bag(String color);
}
//包包工厂类,具有制作包包的功能
public class BagFactory implements ByBag{
@Override
public void bag(String color) {
System.out.println("为您制作了一款颜色为"+color+"的包");
}
}
//包包工厂代理类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class BagProxy implements InvocationHandler{
private Object fattory;
public Object getFattory() {
return fattory;
}
public void setFattory(Object fattory) {
this.fattory = fattory;
}
@Override
public Object invoke(Object proxy,Method method,Object[] args)throws Throwable {
frontService();
method.invoke(fattory, args);
endService();
return null;
}
public void frontService() {
System.out.println("售前服务");
}
public void endService() {
System.out.println("售后服务");
}
public Object getProxyInstence() {
return Proxy.newProxyInstance(fattory.getClass().getClassLoader(), fattory.getClass().getInterfaces(), this);
}
}
//测试类
public class Test {
public static void main(String[] args) {
BagFactory factory=new BagFactory();
BagProxy proxy=new BagProxy();
proxy.setFattory(factory);
ByBag run=(ByBag)proxy.getProxyInstence();
run.bag("蓝色");
}
}
执行结果:
售前服务
为您制作了一款颜色为蓝色的包
售后服务
上面代理类中各个步骤的方法写得比较分散,也可以像下面这样集合到一个方法里面,自行取舍:
public class TargetProxy {
public static Object getTarget(T t) {
//新构建了一个新的代理类的对象
return Proxy.newProxyInstance(t.getClass().getClassLoader(), t.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// proxy就是目标对象t,method就是调用目标对象中方法,args就是调用目标对象中方法的参数。
//比如说:代理对象.method1(),这时proxy就是目标类,method1就是method,args就是method1方法参数。
System.out.println("执行方法前...");
Object invoke = method.invoke(t, args);
System.out.println("执行方法后...");
return invoke;
}
});
}
}
无需接口,通过继承
//目标类
public class Target {
public void method1() {
System.out.println("method1 running ...");
}
public void method2() {
System.out.println("method2 running ...");
}
public int method3(Integer i) {
System.out.println("method3 running ...");
return i;
}
}
//代理类
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class TargetProxy {
public static Object getProxy(T t) {
Enhancer en = new Enhancer(); //帮我们生成代理对象
en.setSuperclass(t.getClass());//设置要代理的目标类(设置代理对象的父类)
en.setCallback(new MethodInterceptor() {//代理要做什么
@Override
public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("执行方法前。。。");
//调用原有方法
Object invoke = methodProxy.invokeSuper(object, args);
// Object invoke = method.invoke(t, args);// 作用等同与上面。
System.out.println("执行方法后。。。");
return invoke;
}
});
return en.create();
}
}
//测试类
public class TargetUser {
public static void main(String[] args) {
Target target = (Target) TargetProxy.getProxy(new Target());
target.method1();
}
}
执行结果:
执行方法前。。。
method1 running ...
执行方法后。。。