代理:从文字意思解读,也就是说代替某个人完成某件事,代替打理。
你现在生病了,需要看病,但是你自己没法给自己看病,因此你需要医生,医生替你看病。
假设你是一个歌星,很红,你只会唱歌,对接单子这种事非常不感冒,因此你需要一个经济人,经纪人负责接活谈钱,时间安排,你只需要负责唱歌就行了。这就是代理。
还是以歌星为例:
TargetClass是一个歌手,他只会唱歌,但是他需要钱来养活自己才可以去唱歌,不巧的是他对接单子这种事非常不感冒,因此他请了一个经纪人
package com.sxt.target;
?
/**
* 被代理的类
*/
public class TargetClass {
public void sing(){
System.out.println("歌手:去唱歌");
}
}
经纪人:ProxyClass 负责安排时间,接活
package com.sxt.target;
?
/**
* 代理类
*/
public class ProxyClass {
?
// 代理的类对象
TargetClass targetClass;
?
public ProxyClass(TargetClass targetClass) {
this.targetClass = targetClass;
}
?
public void sing(){
System.out.println("经纪人:确定时间");
System.out.println("经纪人:下周日");
targetClass.sing();
}
}
?
package com.sxt.target;
?
public class Test {
public static void main(String[] args) {
// 被代理的类对象
TargetClass targetClass = new TargetClass();
// 代理类对象
ProxyClass proxyClass = new ProxyClass(targetClass);
proxyClass.sing();
}
}
输出结果:
经纪人:确定时间
经纪人:下周日
歌手:去唱歌
动态的为需要代理的类,创建了一个代理类,.不再需要开发者定义具体的代理的类.这种方式,就是动态代理.JDK为此制定了一个标准.
proxy:是所有代理类的基类,父类
proxy提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类.
public static Object newProxyInstance(ClassLoader loader,//类加载器 当前类的加载器
Class<?>[] interfaces,//interfaces 接口的Class对象
InvocationHandler handler) // hanlder 代理类的处理器
throws IllegalArgumentException
返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
接口:InvocationHandler 与代理类关联调用程序的处理器
package com.sxt.target;
?
public class config {
// 开启事务方法的前缀
public static String[] preFix = {"add","update","delete"};
}
?
package com.sxt.target;
?
/**
* 被代理类的接口
*/
public interface TargetClassInteterface {
public void addUser();
public void deleteUser();
public void updateUser();
public void selectUser();
}
?
package com.sxt.target;
?
/**
* 具体的代理类
*/
public class TargetClass implements TargetClassInteterface {
package com.sxt.target;
?
/**
* 事务管理器,具体的增强
*/
public class TransctionManager {
?
public void beginTrancation(){
System.out.println("开启事务");
}
?
public void commitTrancation(){
System.out.println("提交事务");
}
?
}
?
package com.sxt.target;
?
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
?
public class ProxyHanlder implements InvocationHandler {
?
// 被代理的目标 此时类型时 Object 那么传入任何类型都可以
private Object proxyTarget;
?
public ProxyHanlder(Object proxyTarget) {
this.proxyTarget = proxyTarget;
}
?
package com.sxt.target;
?
import java.lang.reflect.Proxy;
?
public class Test {
?
public static void main(String[] args) {
// 创建了被代理的目标
TargetClassInteterface targetInterface = new TargetClass();
//创建代理类的处理器
ProxyHanlder handler = new ProxyHanlder(targetInterface);
//创建代理类
TargetClassInteterface proxyObj = (TargetClassInteterface) Proxy.newProxyInstance(Test.class.getClassLoader(), new Class[] {TargetClassInteterface.class}, handler);
proxyObj.addUser();
System.out.println("======================");
proxyObj.deleteUser();
System.out.println("======================");
proxyObj.updateUser();
System.out.println("======================");
proxyObj.selectUser();
System.out.println("======================");
}
?
}
?
输出结果:
开启事务
添加方法
提交事务
======================
开启事务
删除方法
提交事务
======================
开启事务
修改方法
提交事务
======================
查询方法
======================
package com.sxt.target.target;
?
import java.lang.reflect.Proxy;
?
public class Test {
?
public static void main(String[] args) {
?
// 保存生成的文件
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
?
?
// 创建了被代理的目标
TargetClassInteterface targetInterface = new TargetClass();
//创建代理类的处理器
ProxyHanlder handler = new ProxyHanlder(targetInterface);
//创建代理类
TargetClassInteterface proxyObj = (TargetClassInteterface) Proxy.newProxyInstance(Test.class.getClassLoader(), new Class[] {TargetClassInteterface.class}, handler);
proxyObj.addUser();
System.out.println("======================");
?
}
?
}
?
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");然后打开你的本地文件位置,找到D:\workspace2019_12_10\ide-code\java-spring-proxy\com\sun\proxy下的$Proxy0.class文件,再经过反编译工具编译,最后变成下面这段代码啦。
源码分析代码
package com.sun.proxy;
?
import com.sxt.target2.TargetClassInteterface;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
// 生成的代理类 $Proxy0 是 Proxy 子类 且是 TargetClassInteterface 实现类
// 那么这个代理类 就要有 TargetClassInteterface 里面抽象方法
public final class $Proxy0 extends Proxy implements TargetClassInteterface {
private static Method m0; //============> Object类中的 hashCode
private static Method m1; //============> Object类中的 equals
private static Method m2; // ============> Object类中的 toString
private static Method m3; // =============> 实现了接口中 addUser 方法
static
{
try
{
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m3 = Class.forName("com.sxt.target2.TargetClassInteterface").getMethod("addUser", new Class[] { Class.forName("java.lang.String") });
return;
}
catch (NoSuchMethodException localNoSuchMethodException)
{
throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
}
catch (ClassNotFoundException localClassNotFoundException)
{
throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
}
}
// 创建代理类对象 InvocationHandler 对象 本质上就是传入 ProxyHanlder 自己定义的代理类程序处理器
public $Proxy0(InvocationHandler paramInvocationHandler)
throws
{
// 调用父类的有参构造方法 : 将自己定义 ProxyHanlder 传给Proxy
super(paramInvocationHandler);
// 将自己定义的处理器 赋值给了 Proxy 类中 h 成员变量
}
public final boolean equals(Object paramObject)
throws
{
try
{
return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
// 在 测试类中,使用创建出来的代理对象 调用 addUser ,其实就是调用此处的addUser
public final void addUser(String paramString)
throws