代理就是将一个对象的方法进行增强,让方法更有丰富的内容。主要是解决在一个原来的业务逻辑上添加一些辅助性的信息,让业务逻辑更加完善丰富。
1.jdk自带的动态代理
只能进行接口的动态代理。静态代理只能代理一种接口实现的类。动态代理可以对实现任何接口的实现类进行代理。
同时可以代理一个接口中的所有方法。
public class ProxyFactory {
//只能是有接口的类才能被代理
//o:就是接口实现的实例Student()
public Object getProxyIntenst(Object o){
return Proxy.newProxyInstance(o.getClass().getClassLoader(), o.getClass().getInterfaces(), new InvocationHandler() {
//这部分一般情况下写成单独的类
//如果代理方法中没有返回值,那么返回就是null
//proxy:对应的代理类,基本用不上
//method:是接口指定的方法
//args:方法需要的参数
//Object:实际方法返回的值
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开始:代理增强信息");
//o是实现接口的具体实现类
method.invoke(o,args);
System.out.println("结束:代理增强信息");
return null;
}
});
}
}
public static void main(String[] args) {
IPerson iPerson = new Student("jizhou");
ProxyFactory proxyFactory = new ProxyFactory();
IPerson proxyIntenst = (IPerson)proxyFactory.getProxyIntenst(iPerson);
proxyIntenst.doSometing();
}
-
实现原理
jdk是通过反射的方法进行动态代理类的生成,然后生成相应的代理对象。
①通过ProxyGenerator.generateProxyClass()方法实现代理类class字节码的生成,
②然后通过Proxy.defineClass0()本地方法将class字节码文件加载到jvm中,
③通过反射创建代理类对象
-
动态生成的代理类
代理了所有的方法,包括tostring等相关方法,下边的代码只是显示了一个方法的实现。
# 通过ProxyGenerator.generateProxyClass()方法实现代理类class字节码,生成的代理类
public final class ProxyPerson extends Proxy implements IPerson {
private static Method m3;
static {
try {
m3 = Class.forName("org.example.pojo.IPerson").getMethod("doSometing");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
public ProxyPerson(InvocationHandler var1) throws {
super(var1);
}
//关键代理方法 h就是InvocationHandler接口的实现
public final void doSometing() throws {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
}
-
思考
- 动态代理可以修改入参。mybatis框架生成的mapper就是动态代理生成的代理类。
- 处理的代理业务和接口实现完全分离。
- 代理对象任务执行的依旧是真是对象
- 在框架中大量应用
2.CGlib实现的动态代理
能够实现对普通类的代理,不需要接口的实现即可完成类的代理。
//被代理的类
public class User {
public void addInfo(){
System.out.println("添加业务信息");
}
}
//生成代理类的工厂
public class ProxyFactory implements MethodInterceptor {
private Object target;
public ProxyFactory(Object o){
target = o;
}
//Enhancer生成代理类
public Object getProxyInstance(){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
//代理增强类
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("代理开始********");
method.invoke(target,objects);
System.out.println("代理开始********");
return null;
}
}
//使用
public static void main(String[] args){
User user = new User();
ProxyFactory proxyFactory = new ProxyFactory(user);
User proxyInstance = (User)proxyFactory.getProxyInstance();
System.out.println(proxyInstance.getClass());
proxyInstance.addInfo();
}