转自:https://www.cnblogs.com/rjzheng/p/8750265.html
一 借助JDK的API实现:
1.先创建一个接口,并实现它
public interface Person {
void eat();
}
public class PersonImpl implements Person {
@Override
public void eat() {
System.out.println("eat…………");
}
}
2.实现InvocationHandler:每一个动态代理类都要实现这个接口
public class PersonInvocationHandler implements InvocationHandler {
//我们要代理的真实对象
private Object obj;
public PersonInvocationHandler(Object obj) {
this.obj = obj;
}
/\*\*
\* Object proxy:
\* 1. 可以使用反射获取代理对象的信息(也就是proxy.getClass().getName())。
\* 2. 可以将代理对象返回以进行连续调用,这就是proxy存在的目的,因为this并不是代理对象。
\*/
@Override
public Object invoke(Object proxy, Method method, Object\[\] args) throws Throwable {
System.out.println("before eat.......");
//当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
method.invoke(obj, args);
System.out.println("after eat.......");
return null;
}
}
3.测试
public class JdkTest {
public static void main(String[] args) {
PersonInvocationHandler personInvocationHandler = new PersonInvocationHandler(new PersonImpl());
Person personProxy = (Person) Proxy.newProxyInstance(PersonImpl.class.getClassLoader(),
PersonImpl.class.getInterfaces(), personInvocationHandler);
personProxy.eat();
}
}
返回结果:
二 自定义动态代理
1.自定义InvocationHandler
public interface MyInvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}
2.实现自定义的MyInvocationHandler
public class PersonInvocationHandler implements MyInvocationHandler {
//我们要代理的真实对象
private Object obj;
public PersonInvocationHandler(Object obj) {
this.obj = obj;
}
/\*\*
\* Object proxy:
\* 1. 可以使用反射获取代理对象的信息(也就是proxy.getClass().getName())。
\* 2. 可以将代理对象返回以进行连续调用,这就是proxy存在的目的,因为this并不是代理对象。
\*/
@Override
public Object invoke(Object proxy, Method method, Object\[\] args) throws Throwable {
System.out.println("before eat.......");
//当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
method.invoke(obj, args);
System.out.println("after eat.......");
return null;
}
}
3.自定义ClassLoader
public class MyClassLoader extends ClassLoader{
private File classPathFile;
public MyClassLoader() {
String classPath = MyClassLoader.class.getResource("").getPath();
this.classPathFile = new File(classPath);
}
public Class<?> findClass(String name) {
String className = MyClassLoader.class.getPackage().getName() + "." + name;
if (classPathFile != null){
File file = new File(classPathFile, name + ".class");
FileInputStream inputStream = null;
ByteArrayOutputStream outputStream = null;
try {
inputStream = new FileInputStream(file);
outputStream = new ByteArrayOutputStream();
byte\[\] buf = new byte\[1024\];
int len ;
while ((len = inputStream.read(buf)) != -1){
outputStream.write(buf, 0, len);
}
return defineClass(className, outputStream.toByteArray(), 0, outputStream.size());
}catch (Exception e){
e.printStackTrace();
}finally {
if(null!=inputStream){
try {
inputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(null!=outputStream){
try {
outputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
return null;
}
}
4.自定义Proxy代理类
主要流程:1.将源码输入到Java文件
2.将Java文件编译成class文件
3.将class加载进jvm
4.返回代理类对象
public class MyProxy {
public static final String ln = "\r\n";
public static Object newProxyInstance(MyClassLoader classLoader,
Class<?>\[\] interfaces, MyInvocationHandler handler) {
try {
//1.java源码
String src = generateSrc(interfaces);
//2.将源码输出到Java文件中
String filePath = MyProxy.class.getResource("").getPath();
System.out.println(filePath);
File file = new File(filePath + "$Proxy0.java");
FileWriter fw = new FileWriter(file);
fw.write(src);
fw.flush();
fw.close();
//3.将Java文件编译成class文件
JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager manager = javaCompiler.getStandardFileManager(null, null, null);
Iterable iterable = manager.getJavaFileObjects(file);
JavaCompiler.CompilationTask task = javaCompiler.getTask(null, manager, null, null,null, iterable);
task.call();
manager.close();
//4.将class加载进jvm
Class proxyClass = classLoader.findClass("$Proxy0");
file.delete();
//5.返回代理类对象
Constructor constructor = proxyClass.getConstructor(MyInvocationHandler.class);
return constructor.newInstance(handler);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
//Java源码
private static String generateSrc(Class<?>\[\] interfaces) {
// TODO Auto-generated method stub
StringBuffer sb = new StringBuffer();
sb.append("package xin.hangzhi.jdk.proxy.demo.custom;" + ln);
sb.append("import java.lang.reflect.Method;" + ln);
sb.append("public class $Proxy0 implements " + interfaces\[0\].getName() + "{" + ln);
sb.append("private MyInvocationHandler h;"+ln);
sb.append("public $Proxy0(MyInvocationHandler h) { " + ln);
sb.append("this.h = h;"+ln);
sb.append("}" + ln);
for (Method m : interfaces\[0\].getMethods()) {
sb.append("public " + m.getReturnType().getName() + " "
+ m.getName() + "() {" + ln);
sb.append("try{" + ln);
sb.append("Method m = " + interfaces\[0\].getName()
+ ".class.getMethod(\\"" + m.getName()
+ "\\",new Class\[\]{});" + ln);
sb.append("this.h.invoke(this,m,null);" + ln);
sb.append("}catch(Throwable e){" + ln);
sb.append("e.printStackTrace();" + ln);
sb.append("}"+ln);
sb.append("}"+ln);
}
sb.append("}" + ln);
return sb.toString();
}
}
5.测试结果
手机扫一扫
移动阅读更方便
你可能感兴趣的文章