代理(Proxy)是一種設計模式,提供了對目標對象另外的訪問方式;即經過代理對象訪問目標對象.這樣作的好處是:能夠在目標對象實現的基礎上,加強額外的功能操做,即擴展目標對象的功能。符合開閉原則。代理模式屬於結構型 模式,有靜態代理和動態代理。java
需求:如今咱們須要根據類型來分別把數據上傳到不一樣Ftp服務。設計模式
/** * 數據的模型類 */
public static class Data {
private Integer type;
private String name;
private String sex;
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
public static interface IFTPService {
void upload(Data data);
}
public static class FTPService implements IFTPService {
@Override
public void upload(Data data) {
System.out.println("Data{" +
"type=" + data.getType() +
", name='" + data.getName() + '\'' +
", sex='" + data.getSex() + '\'' +
'}');
}
}
public static class FTPServiceStaticProxy implements IFTPService {
private IFTPService ftpService;
// 靜態代理 構造注入的方式賦值
public FTPServiceStaticProxy(IFTPService ftpService) {
this.ftpService = ftpService;
}
@Override
public void upload(Data data) {
before();
if (data.getType() % 2 == 0) {
System.out.println("上傳到服務器 1");
ftpService.upload(data);
} else {
System.out.println("上傳到服務器 2");
ftpService.upload(data);
}
after();
}
private void before(){
System.out.println("Proxy before method.");
}
private void after(){
System.out.println("Proxy after method.");
}
}
public static void main(String[] args) {
Data data = new Data();
data.setName("Name Zhuang San");
data.setSex("男");
data.setType(1);
new FTPServiceStaticProxy(new FTPService()).upload(data);
Data data2 = new Data();
data.setName("Name Wan Wu");
data.setSex("男");
data.setType(2);
new FTPServiceStaticProxy(new FTPService()).upload(data);
}
複製代碼
動態代理有如下特色:數組
/** * 數據的模型類 */
public static class Data {
private Integer type;
private String name;
private String sex;
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
public static interface IFTPService {
void upload(Data data);
}
public static class FTPService implements IFTPService {
@Override
public void upload(Data data) {
System.out.println("Data{" +
"type=" + data.getType() +
", name='" + data.getName() + '\'' +
", sex='" + data.getSex() + '\'' +
'}');
}
}
public static class JDKProxyFTPService implements InvocationHandler {
private Object target;
public Object upload(Object target) {
this.target = target;
Class<?> clazz = target.getClass();
// 如何實現的代理?
return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 只讓 upload 方法進入
if (!"upload".equals(method.getName())) return method.invoke(target, args);
before(args[0]);
Object r = method.invoke(target, args);
after();
return r;
}
private void before(Object data){
System.out.println("Proxy before method.");
if (data instanceof Data) { // 判斷是否屬於 -- Data 模型
Data d = (Data) data;
if (d.getType() % 2 == 0)
System.out.println("上傳到服務器 1");
else
System.out.println("上傳到服務器 2");
}
}
private void after(){
System.out.println("Proxy after method.");
}
}
public static void main(String[] args) {
IFTPService ftpService = (IFTPService) new JDKProxyFTPService().upload(new FTPService());
Data data = new Data();
data.setName("Name Zhuang San");
data.setSex("男");
data.setType(1);
ftpService.upload(data);
}
複製代碼
咱們都知道 JDK Proxy 採用字節重組,從新生的對象來替代原始的對象以達到動態代理的目的。JDK Proxy 生成對象的步驟以下:服務器
public static void main(String[] args) throws IOException {
//經過反編譯工具能夠查看源代碼
byte [] bytes = ProxyGenerator.generateProxyClass("$Proxy0", new Class[]{IFTPService.class});
FileOutputStream os = new FileOutputStream("E://$Proxy0.class");
os.write(bytes);
os.close();
}
複製代碼
使用反編譯工具,獲得java代碼以下:app
package com.reape.design.pattern.proxy;
import java.lang.reflect.*;
import com.reape.design.pattern.proxy.*;
// 繼承了Proxy類 接口咱們的 JDKIFTPService
public final class $Proxy0 extends Proxy implements JDKIFTPService {
private static Method m1;
private static Method m3;
private static Method m2;
private static Method m0;
public $Proxy0(final InvocationHandler invocationHandler) {
super(invocationHandler);
}
// 重寫了 toString hashCode equals 指向了原來的地址
public final boolean equals(final Object o) {
try {
return (boolean)super.h.invoke(this, $Proxy0.m1, new Object[] { o });
}
catch (Error | RuntimeException error) {
throw new Error();
}
catch (Throwable t) {
throw new UndeclaredThrowableException(t);
}
}
public final void upload(final JDKData jdkData) {
try {
super.h.invoke(this, $Proxy0.m3, new Object[] { jdkData });
}
catch (Error | RuntimeException error) {
throw new Error();
}
catch (Throwable t) {
throw new UndeclaredThrowableException(t);
}
}
public final String toString() {
try {
return (String)super.h.invoke(this, $Proxy0.m2, null);
}
catch (Error | RuntimeException error) {
throw new Error();
}
catch (Throwable t) {
throw new UndeclaredThrowableException(t);
}
}
public final int hashCode() {
try {
return (int)super.h.invoke(this, $Proxy0.m0, null);
}
catch (Error | RuntimeException error) {
throw new Error();
}
catch (Throwable t) {
throw new UndeclaredThrowableException(t);
}
}
static {
try {
$Proxy0.m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
$Proxy0.m3 = Class.forName("com.reape.design.pattern.proxy.JDKIFTPService").getMethod("upload", Class.forName("com.reape.design.pattern.proxy.JDKData"));
$Proxy0.m2 = Class.forName("java.lang.Object").getMethod("toString", (Class<?>[])new Class[0]);
$Proxy0.m0 = Class.forName("java.lang.Object").getMethod("hashCode", (Class<?>[])new Class[0]);
}
catch (NoSuchMethodException ex) {
throw new NoSuchMethodError(ex.getMessage());
}
catch (ClassNotFoundException ex2) {
throw new NoClassDefFoundError(ex2.getMessage());
}
}
}
複製代碼
// 1. ClassLoader 自定義
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class MyClassLoader extends ClassLoader{
private File classPathFile;
public MyClassLoader(){
String classPath = MyClassLoader.class.getResource("").getPath();
this.classPathFile = new File(classPath);
}
protected Class<?> findClass(String name) throws ClassNotFoundException {
String className = MyClassLoader.class.getPackage().getName() + "." + name;
if(classPathFile != null){
File classFile = new File(classPathFile,name.replaceAll("\\.","/") + ".class");
if(classFile.exists()){
FileInputStream in = null;
ByteArrayOutputStream out = null;
try{
in = new FileInputStream(classFile);
out = new ByteArrayOutputStream();
byte [] buff = new byte[1024];
int len;
while ((len = in.read(buff)) != -1){
out.write(buff,0,len);
}
return defineClass(className,out.toByteArray(),0,out.size());
}catch (Exception e){
e.printStackTrace();
}finally {
if(null != in){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(out != null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
return null;
}
}
// 2. 動態代理實現的接口類
import java.lang.reflect.Method;
/** * 動態代理實現的接口類 */
public interface MyInvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}
3. 生成java文件編譯爲class寫入jvm,動態代理 /** * 用來生成源代碼的工具類 */ public class MyProxy {
private static final String ln = "\r\n";
private static final String t = "\t";
public static Object newProxyInstance(MyClassLoader classLoader, Class<?> [] interfaces, MyInvocationHandler h){
try {
// 1.動態生成源代碼文件
String src = generateSrc(interfaces);
//二、Java 文件輸出磁盤
String filePath = MyProxy.class.getResource("").getPath();
System.out.println(filePath);
File f = new File(filePath + "$Proxy0.java");
FileWriter fw = null;
fw = new FileWriter(f);
fw.write(src);
fw.flush();
fw.close();
//三、把生成的.java 文件編譯成.class 文件
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager manage = compiler.getStandardFileManager(null,null,null);
Iterable iterable = manage.getJavaFileObjects(f);
JavaCompiler.CompilationTask task =
compiler.getTask(null,manage,null,null,null, iterable);
task.call();
manage.close();
//四、編譯生成的.class 文件加載到 JVM 中來
Class<Object> proxyClass = (Class<Object>) classLoader.findClass("$Proxy0");
Constructor<Object> c = proxyClass.getConstructor(MyInvocationHandler.class);
// f.delete();
//五、返回字節碼重組之後的新的代理對象
return c.newInstance(h);
} catch (IOException | InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
private static String generateSrc(Class<?>[] interfaces){
// interfaces ---> 須要實現的接口的類
StringBuilder sb = new StringBuilder();
sb.append("package com.reape.design.pattern.proxy.handwriting;" + ln);
sb.append("import java.lang.reflect.*;" + ln);
sb.append("public class $Proxy0 implements").append(interfacesToString(interfaces));
sb.append(" {").append(ln);
sb.append(t + "private com.reape.design.pattern.proxy.handwriting.MyInvocationHandler h;" + ln);
sb.append(t + "public $Proxy0(com.reape.design.pattern.proxy.handwriting.MyInvocationHandler h) { " + ln);
sb.append(t + t + "this.h = h;" + ln);
sb.append(t + "}" + ln);
for (Class<?> anInterface : interfaces) {
for (Method m : anInterface.getMethods()) {
Class<?>[] params = m.getParameterTypes();
Class<?> result = m.getReturnType();
sb.append(t + "public final ")
.append(resultToString(result))
.append(" ")
.append(m.getName())
.append("(")
.append(paramsToString(params))
.append(") {").append(ln);
sb.append(t + t + "try {" + ln);
sb.append(t + t + t)
.append(returnToString(result))
.append("h.invoke(this, " + "Class.forName(\"")
// .append(anInterface.getName())
.append("com.reape.design.pattern.proxy.JDKFTPService")
.append("\")")
.append(".getMethod(").append("\"").append(m.getName()).append("\"").append(", ")
.append(paramsFormNameToString(params))
.append(")").append(", new Object[]{ p0 });").append(ln);
sb.append(t + t + "}" + ln);
sb.append(t + t + "catch(Error | RuntimeException error) { error.printStackTrace();" + ln);
sb.append(t + t + t + "throw new Error();" + ln);
sb.append(t + t + "}" + ln);
sb.append(t + t + "catch (Throwable t) {" + ln);
sb.append(t + t + t + "throw new UndeclaredThrowableException(t);" + ln);
sb.append(t + t + "}" + ln);
sb.append(t + "}" + ln);
}
}
sb.append("}" + ln);
return sb.toString();
}
/** * 接口類數組轉 String * @param interfaces 接口類數組 * @return 字符串 */
private static String interfacesToString(Class<?>[] interfaces) {
if (interfaces.length < 1) return "";
StringBuilder sb = new StringBuilder();
for (Class<?> anInterface : interfaces) {
sb.append(" ").append(anInterface.getName()).append(",");
}
return sb.substring(0, sb.length() - 1);
}
private static String paramsToString(Class<?>[] params) {
if (params.length < 1) return "";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < params.length; i++) {
sb.append(params[i].getName()).append(" ").append("p").append(i).append(", ");
}
return sb.substring(0, sb.length() - 2);
}
private static String paramsFormNameToString(Class<?>[] params) {
if (params.length < 1) return "";
StringBuilder sb = new StringBuilder();
for (Class<?> param : params) {
sb.append("Class.forName(\"").append(param.getName()).append("\"), ");
}
return sb.substring(0, sb.length() - 2);
}
private static String resultToString(Class<?> result) {
String name = result.getName();
return "void".equals(name) ? "void" : name;
}
private static String returnToString(Class<?> result) {
String name = result.getName();
return "void".equals(name) ? "" : "return (" + name + ") ";
}
}
// 4.測試
public class Test implements MyInvocationHandler {
private Object target;
public Object get(Object target) {
this.target = target;
Class<?> clazz = target.getClass();
return MyProxy.newProxyInstance(new MyClassLoader(), clazz.getInterfaces(), this);
}
private void before(Object data){
System.out.println(data);
System.out.println("Proxy before method.");
}
private void after(){
System.out.println("Proxy after method.");
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 只讓 upload 方法進入
if (!"upload".equals(method.getName())) return method.invoke(target, args);
before(args[0]);
Object r = method.invoke(target, args);
after();
return r;
}
public static void main(String[] args) {
JDKIFTPService ftpService = (JDKIFTPService) new Test().get(new JDKFTPService());
JDKData data = new JDKData();
data.setName("Name Zhuang San");
data.setSex("男");
data.setType(1);
ftpService.upload(data);
}
}
// 上面的代碼寫考慮的不是很完整
// 有不少判斷的地方沒有判斷以及重寫 toString ,equals 等
// java的代理是編譯爲class文件而後寫入的到jvm節約的了內存消耗,可是跟cglib對比仍是差很遠
// cglib是字節碼操做
複製代碼
// 導入jar包
// 1. asm.jar
// 2. cglib.jar
public class JDKData {
private Integer type;
private String name;
private String sex;
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
public class JDKFTPService implements JDKIFTPService {
@Override
public void upload(JDKData data) {
System.out.println("Data{" +
"type=" + data.getType() +
", name='" + data.getName() + '\'' +
", sex='" + data.getSex() + '\'' +
'}');
}
}
public class CglibJDK implements MethodInterceptor {
public Object getInstance(Class<?> clazz) throws Exception{
Enhancer enhancer = new Enhancer();
//要把哪一個設置爲即將生成的新類父類
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//業務的加強
before(objects[0]);
Object obj = methodProxy.invokeSuper(o,objects);
after();
return obj;
}
private void before(Object data){
System.out.println("Proxy before method.");
System.out.println(data);
if (data instanceof JDKData) { // 判斷是否屬於 -- Data 模型
JDKData d = (JDKData) data;
if (d.getType() % 2 == 0)
System.out.println("上傳到服務器 1");
else
System.out.println("上傳到服務器 2");
}
}
private void after(){
System.out.println("Proxy after method.");
}
}
// 測試
public static void main(String[] args) {
try {
JDKFTPService obj = (JDKFTPService) new CglibJDK().getInstance(JDKFTPService.class);
JDKData data = new JDKData();
data.setName("Name Zhuang San");
data.setSex("男");
data.setType(1);
obj.upload(data);
} catch (Exception e) {
e.printStackTrace();
}
}
// 編譯獲得class文件
package com.reape.design.pattern.proxy.cglib;
import net.sf.cglib.reflect.*;
import net.sf.cglib.core.*;
import net.sf.cglib.proxy.*;
import java.lang.reflect.*;
public class JDKFTPService$$EnhancerByCGLIB$$5a7831ef$$FastClassByCGLIB$$5a694231 extends FastClass {
public JDKFTPService$$EnhancerByCGLIB$$5a7831ef$$FastClassByCGLIB$$5a694231(final Class clazz) {
super(clazz);
}
public int getIndex(final Signature signature) {
final String string = signature.toString();
switch (string.hashCode()) {
case -2055565910: {
if (string.equals("CGLIB$SET_THREAD_CALLBACKS([Lnet/sf/cglib/proxy/Callback;)V")) {
return 12;
}
break;
}
case -1882565338: {
if (string.equals("CGLIB$equals$1(Ljava/lang/Object;)Z")) {
return 15;
}
break;
}
case -1457535688: {
if (string.equals("CGLIB$STATICHOOK1()V")) {
return 19;
}
break;
}
case -1411842725: {
if (string.equals("CGLIB$hashCode$3()I")) {
return 18;
}
break;
}
case -894172689: {
if (string.equals("newInstance(Lnet/sf/cglib/proxy/Callback;)Ljava/lang/Object;")) {
return 6;
}
break;
}
case -623122092: {
if (string.equals("CGLIB$findMethodProxy(Lnet/sf/cglib/core/Signature;)Lnet/sf/cglib/proxy/MethodProxy;")) {
return 20;
}
break;
}
case -508378822: {
if (string.equals("clone()Ljava/lang/Object;")) {
return 3;
}
break;
}
case -419626537: {
if (string.equals("setCallbacks([Lnet/sf/cglib/proxy/Callback;)V")) {
return 11;
}
break;
}
case 560567118: {
if (string.equals("setCallback(ILnet/sf/cglib/proxy/Callback;)V")) {
return 7;
}
break;
}
case 773140094: {
if (string.equals("CGLIB$upload$0(Lcom/reape/design/pattern/proxy/cglib/JDKData;)V")) {
return 14;
}
break;
}
case 811063227: {
if (string.equals("newInstance([Ljava/lang/Class;[Ljava/lang/Object;[Lnet/sf/cglib/proxy/Callback;)Ljava/lang/Object;")) {
return 5;
}
break;
}
case 840180909: {
if (string.equals("upload(Lcom/reape/design/pattern/proxy/cglib/JDKData;)V")) {
return 8;
}
break;
}
case 973717575: {
if (string.equals("getCallbacks()[Lnet/sf/cglib/proxy/Callback;")) {
return 10;
}
break;
}
case 1221173700: {
if (string.equals("newInstance([Lnet/sf/cglib/proxy/Callback;)Ljava/lang/Object;")) {
return 4;
}
break;
}
case 1230699260: {
if (string.equals("getCallback(I)Lnet/sf/cglib/proxy/Callback;")) {
return 9;
}
break;
}
case 1306468936: {
if (string.equals("CGLIB$toString$2()Ljava/lang/String;")) {
return 16;
}
break;
}
case 1584330438: {
if (string.equals("CGLIB$SET_STATIC_CALLBACKS([Lnet/sf/cglib/proxy/Callback;)V")) {
return 13;
}
break;
}
case 1800494055: {
if (string.equals("CGLIB$clone$4()Ljava/lang/Object;")) {
return 17;
}
break;
}
case 1826985398: {
if (string.equals("equals(Ljava/lang/Object;)Z")) {
return 0;
}
break;
}
case 1913648695: {
if (string.equals("toString()Ljava/lang/String;")) {
return 1;
}
break;
}
case 1984935277: {
if (string.equals("hashCode()I")) {
return 2;
}
break;
}
}
return -1;
}
public int getIndex(final String s, final Class[] array) {
Label_1103: {
switch (s.hashCode()) {
case -1776922004: {
if (!s.equals("toString")) {
break;
}
switch (array.length) {
case 0: {
return 1;
}
default: {
break Label_1103;
}
}
break;
}
case -1295482945: {
if (!s.equals("equals")) {
break;
}
switch (array.length) {
case 1: {
if (array[0].getName().equals("java.lang.Object")) {
return 0;
}
break Label_1103;
}
default: {
break Label_1103;
}
}
break;
}
case -1053468136: {
if (!s.equals("getCallbacks")) {
break;
}
switch (array.length) {
case 0: {
return 10;
}
default: {
break Label_1103;
}
}
break;
}
case -838595071: {
if (!s.equals("upload")) {
break;
}
switch (array.length) {
case 1: {
if (array[0].getName().equals("com.reape.design.pattern.proxy.cglib.JDKData")) {
return 8;
}
break Label_1103;
}
default: {
break Label_1103;
}
}
break;
}
case -124978609: {
if (!s.equals("CGLIB$equals$1")) {
break;
}
switch (array.length) {
case 1: {
if (array[0].getName().equals("java.lang.Object")) {
return 15;
}
break Label_1103;
}
default: {
break Label_1103;
}
}
break;
}
case -60403779: {
if (!s.equals("CGLIB$SET_STATIC_CALLBACKS")) {
break;
}
switch (array.length) {
case 1: {
if (array[0].getName().equals("[Lnet.sf.cglib.proxy.Callback;")) {
return 13;
}
break Label_1103;
}
default: {
break Label_1103;
}
}
break;
}
case -29025555: {
if (!s.equals("CGLIB$hashCode$3")) {
break;
}
switch (array.length) {
case 0: {
return 18;
}
default: {
break Label_1103;
}
}
break;
}
case 85179481: {
if (!s.equals("CGLIB$SET_THREAD_CALLBACKS")) {
break;
}
switch (array.length) {
case 1: {
if (array[0].getName().equals("[Lnet.sf.cglib.proxy.Callback;")) {
return 12;
}
break Label_1103;
}
default: {
break Label_1103;
}
}
break;
}
case 94756189: {
if (!s.equals("clone")) {
break;
}
switch (array.length) {
case 0: {
return 3;
}
default: {
break Label_1103;
}
}
break;
}
case 147696667: {
if (!s.equals("hashCode")) {
break;
}
switch (array.length) {
case 0: {
return 2;
}
default: {
break Label_1103;
}
}
break;
}
case 161998109: {
if (!s.equals("CGLIB$STATICHOOK1")) {
break;
}
switch (array.length) {
case 0: {
return 19;
}
default: {
break Label_1103;
}
}
break;
}
case 495524492: {
if (!s.equals("setCallbacks")) {
break;
}
switch (array.length) {
case 1: {
if (array[0].getName().equals("[Lnet.sf.cglib.proxy.Callback;")) {
return 11;
}
break Label_1103;
}
default: {
break Label_1103;
}
}
break;
}
case 857604112: {
if (!s.equals("CGLIB$upload$0")) {
break;
}
switch (array.length) {
case 1: {
if (array[0].getName().equals("com.reape.design.pattern.proxy.cglib.JDKData")) {
return 14;
}
break Label_1103;
}
default: {
break Label_1103;
}
}
break;
}
case 1154623345: {
if (!s.equals("CGLIB$findMethodProxy")) {
break;
}
switch (array.length) {
case 1: {
if (array[0].getName().equals("net.sf.cglib.core.Signature")) {
return 20;
}
break Label_1103;
}
default: {
break Label_1103;
}
}
break;
}
case 1543336189: {
if (!s.equals("CGLIB$toString$2")) {
break;
}
switch (array.length) {
case 0: {
return 16;
}
default: {
break Label_1103;
}
}
break;
}
case 1811874389: {
if (!s.equals("newInstance")) {
break;
}
switch (array.length) {
case 1: {
final String name = array[0].getName();
switch (name.hashCode()) {
case -845341380: {
if (name.equals("net.sf.cglib.proxy.Callback")) {
return 6;
}
break;
}
case 1730110032: {
if (name.equals("[Lnet.sf.cglib.proxy.Callback;")) {
return 4;
}
break;
}
}
break Label_1103;
}
case 3: {
if (array[0].getName().equals("[Ljava.lang.Class;") && array[1].getName().equals("[Ljava.lang.Object;") && array[2].getName().equals("[Lnet.sf.cglib.proxy.Callback;")) {
return 5;
}
break Label_1103;
}
default: {
break Label_1103;
}
}
break;
}
case 1817099975: {
if (!s.equals("setCallback")) {
break;
}
switch (array.length) {
case 2: {
if (array[0].getName().equals("int") && array[1].getName().equals("net.sf.cglib.proxy.Callback")) {
return 7;
}
break Label_1103;
}
default: {
break Label_1103;
}
}
break;
}
case 1905679803: {
if (!s.equals("getCallback")) {
break;
}
switch (array.length) {
case 1: {
if (array[0].getName().equals("int")) {
return 9;
}
break Label_1103;
}
default: {
break Label_1103;
}
}
break;
}
case 1951977610: {
if (!s.equals("CGLIB$clone$4")) {
break;
}
switch (array.length) {
case 0: {
return 17;
}
default: {
break Label_1103;
}
}
break;
}
}
}
return -1;
}
public int getIndex(final Class[] array) {
switch (array.length) {
case 0: {
return 0;
}
default: {
return -1;
}
}
}
public Object invoke(final int n, final Object o, final Object[] array) throws InvocationTargetException {
final JDKFTPService$$EnhancerByCGLIB$$5a7831ef jdkftpService$$EnhancerByCGLIB$$5a7831ef = (JDKFTPService$$EnhancerByCGLIB$$5a7831ef)o;
try {
switch (n) {
case 0: {
return new Boolean(jdkftpService$$EnhancerByCGLIB$$5a7831ef.equals(array[0]));
}
case 1: {
return jdkftpService$$EnhancerByCGLIB$$5a7831ef.toString();
}
case 2: {
return new Integer(jdkftpService$$EnhancerByCGLIB$$5a7831ef.hashCode());
}
case 3: {
return jdkftpService$$EnhancerByCGLIB$$5a7831ef.clone();
}
case 4: {
return jdkftpService$$EnhancerByCGLIB$$5a7831ef.newInstance((Callback[])array[0]);
}
case 5: {
return jdkftpService$$EnhancerByCGLIB$$5a7831ef.newInstance((Class[])array[0], (Object[])array[1], (Callback[])array[2]);
}
case 6: {
return jdkftpService$$EnhancerByCGLIB$$5a7831ef.newInstance((Callback)array[0]);
}
case 7: {
jdkftpService$$EnhancerByCGLIB$$5a7831ef.setCallback(((Number)array[0]).intValue(), (Callback)array[1]);
return null;
}
case 8: {
jdkftpService$$EnhancerByCGLIB$$5a7831ef.upload((JDKData)array[0]);
return null;
}
case 9: {
return jdkftpService$$EnhancerByCGLIB$$5a7831ef.getCallback(((Number)array[0]).intValue());
}
case 10: {
return jdkftpService$$EnhancerByCGLIB$$5a7831ef.getCallbacks();
}
case 11: {
jdkftpService$$EnhancerByCGLIB$$5a7831ef.setCallbacks((Callback[])array[0]);
return null;
}
case 12: {
JDKFTPService$$EnhancerByCGLIB$$5a7831ef.CGLIB$SET_THREAD_CALLBACKS((Callback[])array[0]);
return null;
}
case 13: {
JDKFTPService$$EnhancerByCGLIB$$5a7831ef.CGLIB$SET_STATIC_CALLBACKS((Callback[])array[0]);
return null;
}
case 14: {
jdkftpService$$EnhancerByCGLIB$$5a7831ef.CGLIB$upload$0((JDKData)array[0]);
return null;
}
case 15: {
return new Boolean(jdkftpService$$EnhancerByCGLIB$$5a7831ef.CGLIB$equals$1(array[0]));
}
case 16: {
return jdkftpService$$EnhancerByCGLIB$$5a7831ef.CGLIB$toString$2();
}
case 17: {
return jdkftpService$$EnhancerByCGLIB$$5a7831ef.CGLIB$clone$4();
}
case 18: {
return new Integer(jdkftpService$$EnhancerByCGLIB$$5a7831ef.CGLIB$hashCode$3());
}
case 19: {
JDKFTPService$$EnhancerByCGLIB$$5a7831ef.CGLIB$STATICHOOK1();
return null;
}
case 20: {
return JDKFTPService$$EnhancerByCGLIB$$5a7831ef.CGLIB$findMethodProxy((Signature)array[0]);
}
}
}
catch (Throwable t) {
throw new InvocationTargetException(t);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
public Object newInstance(final int n, final Object[] array) throws InvocationTargetException {
try {
switch (n) {
case 0: {
return new JDKFTPService$$EnhancerByCGLIB$$5a7831ef();
}
}
}
catch (Throwable t) {
throw new InvocationTargetException(t);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
public int getMaxIndex() {
return 20;
}
}
// 裏面使用 extends FastClass
// 子類重寫父類的方法
// 父類方法不能是final
複製代碼
代理模式能將代理對象與真實被調用的目標對象分離。框架
必定程度上下降了系統的耦合度,擴展性好。jvm
能夠起到保護目標對象的做用。ide
能夠對目標對象的功能加強。工具
固然,代理模式也是有缺點的:測試
ASM > javassist > 手寫的(java -> class -> 加載)