参考连接:http://modouxiansheng.top/2018/09/14/不学无数-Java代理模式-2018/
代理对象:增强后的对象。
目标对象:被增强后的对象。
1、静态代理
(1)继承:
目标对象:
package dao;
public class UserDaoImpl {
public void query(String name) {
System.out.println("query name = " + name);
}
}
代理对象:
package Proxy;
import dao.UserDaoImpl;
public class LogUserProxy extends UserDaoImpl {
public void query(String name) {
System.out.println("log name = " + name);
System.out.println("query name = " + name);
}
}
package dao;
public interface UserDao {
public void query(String name);
}
目标对象:
package dao;
public class UserDaoImpl implements UserDao {
public void query(String name) {
System.out.println("query name = " + name);
}
}
代理对象:
package Proxy2;
import dao.UserDao;
public class LogUserProxy implements UserDao {
private UserDao userDao;
public LogUserProxy(UserDao userDao) {
this.userDao = userDao;
}
public void query(String name) {
System.out.println("....log.....");
userDao.query(name);
}
}
代理对象:
package Proxy;
import dao.UserDaoImpl;
public class TimerUserProxy extends UserDaoImpl {
public void query(String name) {
System.out.println("Timer name = " + name);
System.out.println("query name = " + name);
}
}
package test;
import Proxy2.LogUserProxy;
import Proxy2.TimerUserProxy;
import dao.UserDao;
import dao.UserDaoImpl;
public class Test {
public static void main(String[] args) {
UserDao userDao = new UserDaoImpl();
UserDao proxy1 = new LogUserProxy(userDao);
UserDao proxy2 = new TimerUserProxy(proxy1);
proxy2.query("张三");
}
}
目标对象和代理对象实现同一个接口,并且代理对象当中包含抽象对象。
2、动态代理
代理:本来应该自己做的事情,却请了别人来做,别请的人就是代理对象。
动态代理:再程序运行过程中产生的这个对象
public static Object new ProxyInstance (ClassLoader load,Class> interfaces,
InvocationHandler h)
最终会调用InvocationHandler的方法
package utils;
import com.sun.xml.internal.bind.v2.runtime.reflect.opt.Const;
import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
public class ProxyUtil {
/**
* 得到一个java文件
* 编译成为一个class
* 通过反射得到一个对象
* return
* @param target
* @return
*/
public static Object newProxyInstance(Object target) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
String content = "";
String packageContent = "package Proxy2;";
Class targetInfo = target.getClass().getInterfaces()[0];
String targetInfoName = targetInfo.getSimpleName();
String importContent = "import " + targetInfo.getName() + ";";
String classContent = "public class $Proxy implements " + targetInfoName + "{";
String fieldContent = "private " + targetInfoName + " target;";
String construterContent = "public $Proxy(" + targetInfoName + " target){" +
"this.target = target;}";
String methodsContent = "";
Method[] methods = targetInfo.getDeclaredMethods();
/**
* public void query(String name) {
* System.out.println("....log.....");
* userDao.query(name);
* }
*/
for (Method method : methods) {
String methodName = method.getName();
Class returnType = method.getReturnType();
Class>[] parameterTypes = method.getParameterTypes();
String argsContent = "";
String argsNames = "";
int i = 0;
for (Class> parameterType : parameterTypes) {
String simpleName = parameterType.getSimpleName();
argsContent += simpleName + " p" + i + ",";
argsNames += "p" + i + ",";
i ++;
}
if (argsContent.length() > 0) {
argsContent = argsContent.substring(0,argsContent.lastIndexOf(",") - 1);
argsNames = argsNames.substring(0,argsNames.lastIndexOf(",") - 1);
}
methodsContent = "public " + returnType + " " + methodName + "(" +
argsContent + "){" + "System.out.println(\"....log.....\");"
+ "target." + methodName + "(" + argsNames + ");}";
}
content += packageContent + importContent + classContent + fieldContent +
construterContent + methodsContent + "}";
File file = new File("g:\\Proxy2\\$Proxy.java");
if (!file.exists()) {
file.createNewFile();
}
FileWriter fileWriter = new FileWriter(file);
fileWriter.flush();
fileWriter.write(content);
fileWriter.close();
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null,null,null);
Iterable units = fileManager.getJavaFileObjects(file);
JavaCompiler.CompilationTask task = compiler.getTask(null,fileManager,null,null,null,units);
task.call();
fileManager.close();
URL[] urls = new URL[]{new URL("file:g:\\\\")};
URLClassLoader urlClassLoader = new URLClassLoader(urls);
Class> clzz = urlClassLoader.loadClass("Proxy2.$Proxy");
Constructor constructor = clzz.getConstructor(targetInfo);
Object proxy = constructor.newInstance(target);
return proxy;
}
}