package com.test.proxy.staticproxy;
import com.test.service.dto.UserDto;
import com.test.service.impl.UserServiceImpl;
/**
* Created by xx
* 2020/8/4.
*/
public class SaticProxyByExtend extends UserServiceImpl {
@Override
public UserDto findHouse(UserDto userDto) {
System.out.printf("come find house,paramer={%s)\r\n", userDto);
long begin = System.currentTimeMillis();
super.findHouse(userDto);
long end = System.currentTimeMillis();
System.out.printf("come find house,result={%s)\r\n",userDto);
System.out.printf("the time of the method costs is{%d}\r\n",end-begin);
return userDto;
}
}
package com.test.proxy.staticproxy;
import com.test.service.UserService;
import com.test.service.dto.UserDto;
/**
* Created by xx
* 2020/8/4.
*/
public class SaticProxyByReference implements UserService {
private UserService userService;
public SaticProxyByReference(UserService userService) {
this.userService = userService;
}
@Override
public UserDto findHouse(UserDto userDto) {
System.out.printf("come find house,paramer={%s)\r\n",userDto);
long begin = System.currentTimeMillis();
userService.findHouse(userDto);
long end = System.currentTimeMillis();
System.out.printf("come find house,result={%s)\r\n",userDto);
System.out.printf("the time of the method costs is{%d}\r\n",end-begin);
return userDto;
}
}
package com.test.proxy.dynamicproxy.cglib;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* Created by xx
* 2020/8/4.
*/
public class CGLibProxyFactory implements MethodInterceptor {
private Enhancer enhancer = new Enhancer();
public <T> T getInstants(Class<T> clazz) {
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return (T) enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.printf("come find house,paramer={%s)\r\n", objects);
long begin = System.currentTimeMillis();
Object result = methodProxy.invokeSuper(o, objects);
long end = System.currentTimeMillis();
System.out.printf("come find house,result={%s)\r\n", result);
System.out.printf("the time of the method costs is{%d}\r\n", end - begin);
return result;
}
}
package com.test.proxy.dynamicproxy.jdkproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* Created by xx
* 2020/8/4.
*/
public class JDKProxyFactory {
public static <T> T getInstants(T obj){
return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.printf("come JDKProxyFactory,paramer={%s)\r\n", args);
long begin = System.currentTimeMillis();
Object result = method.invoke(obj, args);
long end = System.currentTimeMillis();
System.out.printf("leave JDKProxyFactory,result={%s)\r\n", result);
System.out.printf("the time of the method costs is{%d}\r\n", end - begin);
return result;
}
});
}
}
package com.test.proxy.ownproxylower;
import com.test.service.UserService;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* Created by xx
* 2020/8/4.
*/
public class SNProxy {
private static final String CLASS_PATH = System.getProperty("user.dir") + "/" + "/src/main/java";
private static final String PACKAGE = "com.test.proxy.ownproxylower";
private static final String CLASS_NAME = "$Proxy0";
//给指定类生成代理类
public static Object getInstance(UserService userService) {
//java代理类文件
File proxyFile = null;
try {
//1.生成java文件字符串
String src = generateJavaString();
//2.将字符串转换成.java文件
proxyFile = generateFile(src);
//3.编译Java文件,生成.class文件
compileJavaFile(proxyFile);
//4.将.class文件加载到java虚拟机中
Class clazz = loadClass();
//5.通过class反射获得对象,返回对象
Constructor constructor = clazz.getConstructor(UserService.class);
return constructor.newInstance(userService);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} finally {
//6.清除中间生成的.java文件 .class文件
if (proxyFile != null) {
proxyFile.delete();
String javaFilePath = proxyFile.getPath();
String classFilePath = javaFilePath.substring(0, javaFilePath.lastIndexOf(".")) + ".class";
new File(classFilePath).delete();
}
}
return null;
}
private static Class loadClass() throws ClassNotFoundException {
SNClassLoader snClassLoader = new SNClassLoader(CLASS_PATH);
return snClassLoader.loadClass(PACKAGE + "." + CLASS_NAME);
}
private static void compileJavaFile(File proxyFile) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjects(proxyFile);
JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, null, null, compilationUnits);
task.call();
}
private static File generateFile(String src) {
String filePath = CLASS_PATH + "/" + (PACKAGE.replaceAll("[.]", "/")) + "/" + CLASS_NAME + ".java";
File file = new File(filePath);
if (file.exists()) {
file.delete();
}
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
fileOutputStream.write(src.getBytes());
fileOutputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
return file;
}
private static String generateJavaString() {
return "package com.test.proxy.ownproxylower;\n" +
"import com.test.service.UserService;\n" +
"import com.test.service.dto.UserDto;\n" +
"public class $Proxy0 implements UserService {\n" +
" private UserService userService;\n" +
" public $Proxy0(UserService userService) {\n" +
" this.userService = userService;\n" +
" }\n" +
" @Override\n" +
" public UserDto findHouse(UserDto userDto) {\n" +
" System.out.printf(\"come find house,paramer={%s)\\r\\n\", userDto);\n" +
" long begin = System.currentTimeMillis();\n" +
" userService.findHouse(userDto);\n" +
" long end = System.currentTimeMillis();\n" +
" System.out.printf(\"the time of the method costs is{%d}\\r\\n\", end - begin);\n" +
" System.out.printf(\"come find house,result={%s)\\r\\n\", userDto);\n" +
" return userDto;\n" +
" }\n" +
"}\n";
}
}
package com.test.proxy.ownproxylower;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* Created by xx
* 2020/8/4.
*/
@Getter
@Setter
@AllArgsConstructor
public class SNClassLoader extends ClassLoader {
private String classPath;
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] bytes = readClassFile(name);
return super.defineClass(bytes, 0, bytes.length);
}
private byte[] readClassFile(String name) {
String filePath = this.getClassPath() + "/" + (name.replaceAll("[.]", "/")) + ".class";
try (FileInputStream fileInputStream = new FileInputStream(filePath);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();) {
byte[] bytes = new byte[1024];
int count = -1;
while (-1 != (count = fileInputStream.read(bytes))) {
byteArrayOutputStream.write(bytes, 0, count);
}
return byteArrayOutputStream.toByteArray();
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
package com.test;
import com.test.proxy.dynamicproxy.cglib.CGLibProxyFactory;
import com.test.proxy.dynamicproxy.jdkproxy.JDKProxyFactory;
import com.test.proxy.ownproxyhigher.SNProxyFactory;
import com.test.proxy.ownproxylower.SNProxy;
import com.test.proxy.staticproxy.SaticProxyByExtend;
import com.test.proxy.staticproxy.SaticProxyByReference;
import com.test.service.UserService;
import com.test.service.dto.UserDto;
import com.test.service.impl.UserServiceImpl;
import org.junit.Before;
import org.junit.Test;
import sun.misc.ProxyGenerator;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Created by xx
* 2020/8/4.
*/
public class TestProxy {
//定义被代理对象
private UserService userService;
//查询参数
private UserDto userDto;
@Before
public void setUp() {
userService = new UserServiceImpl();
userDto = new UserDto(null, "张辉", "仙鹤门");
}
/**
* 不使用代理的调用方式
*/
@Test
public void test1_NoProxy() {
userService.findHouse(userDto);
}
/**
* 静态代理实现方式1::继承方式实现代理
*/
@Test
public void test2_staticProxyByExtend() {
SaticProxyByExtend saticProxyByExtend = new SaticProxyByExtend();
saticProxyByExtend.findHouse(userDto);
}
/**
* 静态代理实现方式2:使用组合|聚合
*/
@Test
public void test3_staticProxyByReference() {
SaticProxyByReference saticProxyByReference = new SaticProxyByReference(userService);
saticProxyByReference.findHouse(userDto);
}
/**
* 动态代理测试:jdkproxy实现
*/
@Test
public void test4_javaProxy() {
UserService userServiceProxy = JDKProxyFactory.getInstants(this.userService);
userServiceProxy.findHouse(userDto);
}
/**
* 动态代理测试:cglib实现
*/
@Test
public void test5_cgLibProxy() {
UserService userServiceProxy = new CGLibProxyFactory().getInstants(UserServiceImpl.class);
userServiceProxy.findHouse(userDto);
}
/**
* 自定义动态代理测试:低级版的自定义实现
*/
@Test
public void test6_ownProxyLower() {
UserService userServiceProxy = (UserService) SNProxy.getInstance(this.userService);
userServiceProxy.findHouse(new UserDto(null, "张辉", "仙鹤门"));
}
}