静态代理
继承
代理对象继承目标对象,重写目标对象的方法
目标对象:
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 {
@Override
public void query(String name) {
System.out.println("log name=" + name);
super.query(name);
}
}
聚合
目标对象和代理对象实现同一个接口,并且代理对象当中包含着抽象对象。
抽象对象:
package dao;
public interface UserDao {
void query(String name);
}
目标对象:
package dao;
public class UserDaoImpl implements UserDao{
public void query(String name)
{
System.out.println("query name=" + name);
}
}
代理对象:
package proxy;
import dao.UserDao;
import dao.UserDaoImpl;
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.UserDao;
public class TimeUserProxy implements UserDao {
private UserDao userDao;
public TimeUserProxy(UserDao userDao)
{
this.userDao=userDao;
}
public void query(String name) {
System.out.println("time...");
userDao.query(name);
}
}
测试:
package test;
import dao.UserDao;
import dao.UserDaoImpl;
import proxy.LogUserProxy;
import proxy.TimeUserProxy;
public class Test {
public static void main(String[] args) {
UserDao userDao=new UserDaoImpl();
UserDao proxy1=new LogUserProxy(userDao);
UserDao proxy2=new TimeUserProxy(proxy1);
proxy2.query("Jack");
}
}
动态代理
编写代理类
package test;
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*/
public static Object newProxyInstance(Object target) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
String content="";//java文件的内容
String packageContent="package proxy;";//目标类所在包 package proxy;
Class targetInfo=target.getClass().getInterfaces()[0];//得到目标类实现的接口
String targetInfoName=targetInfo.getSimpleName();//得到接口名(不包含包名)
String importContent="import "+targetInfo.getName()+";";//得到导入的接口的完全限定名 import dao.UserDao;
String classContent="public class $Proxy implements "+targetInfoName+"{"; //类名
String fieldContent="private "+targetInfoName+" target;";
String constructContent="public $Proxy("+targetInfoName+" target){"//构造方法
+"this.target=target;}";
String methodsContent="";//得到所有的方法
Method[] declaredMethods=targetInfo.getDeclaredMethods();
for(Method method:declaredMethods)
{
String methodName=method.getName();//得到方法名
Class returnType=method.getReturnType();//得到返回类型
Class<?>[] parameterTypes = method.getParameterTypes();//得到方法参数列表
String argsContent="";//方法参数
String argsName="";//方法参数对象
int i=0;
for(Class<?> parameterType:parameterTypes)
{
String simpleName = parameterType.getSimpleName();
argsContent+=simpleName+" p"+i+",";
argsName+="p "+i+",";
i++;
}
if (argsContent.length()>0) {
argsContent=argsContent.substring(0,argsContent.lastIndexOf(",")-1);
argsName=argsName.substring(0,argsName.lastIndexOf(",")-1);
}
methodsContent="public "+returnType+" "+methodName+"("+argsContent+"){"
+"System.out.println(\"log...\");"
+"target."+methodName+"("+argsName+");}";
}
content+=packageContent+importContent+classContent+fieldContent+constructContent+methodsContent+"}";
//写到磁盘上
File file=new File("d:\\proxy\\$Proxy.java");
if(!file.exists())
{
file.createNewFile();
}
FileWriter fileWriter=new FileWriter(file);
fileWriter.write(content);
fileWriter.flush();
fileWriter.flush();
//编译得到class文件
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();
//加载磁盘上的class文件
URL[] urls=new URL[]{new URL("file:d\\\\")};
URLClassLoader urlClassLoader=new URLClassLoader(urls);
Class $Proxy = urlClassLoader.loadClass("proxy.$Proxy");
Constructor constructor = $Proxy.getConstructor(targetInfo);
Object o = constructor.newInstance(target);
return o;
}
}
#生成的Java文件
package proxy;
import dao.UserDao;
public class $Proxy implements UserDao {
private UserDao target;
public $Proxy(UserDao target) {
this.target = target;
}
public void query(String p) {
System.out.println("log...");
target.query(p);
}
}
测试
package test;
import dao.UserDao;
import dao.UserDaoImpl;
import proxy.LogUserProxy;
import proxy.TimeUserProxy;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
UserDao userDao=new UserDaoImpl();
UserDao proxy = (UserDao)ProxyUtil.newProxyInstance(userDao);
proxy.query("Jack");
}
}
参考函数
getInterfaces()
public static void main(String[] args) {
UserDaoImpl userDao = new UserDaoImpl();
Class iface=userDao.getClass().getInterfaces()[0];
System.out.println(iface);
System.out.println(iface.getSimpleName());
System.out.println(iface.getName());
}
getClass()
public static void main(String[] args) {
UserDaoImpl userDao = new UserDaoImpl();
Class iface=userDao.getClass();
System.out.println(iface);
System.out.println(iface.getName());
System.out.println(iface.getSimpleName());
}
getDeclaredMethods()
public static void main(String[] args) {
UserDao userDao=new UserDaoImpl();
Class iface=userDao.getClass();
Method[] declaredMethods = iface.getDeclaredMethods();
for(Method method:declaredMethods)
{
System.out.println(method.getName());
System.out.println(method.getReturnType());
Class<?>[] parameterTypes = method.getParameterTypes();
for(Class<?> parameterType:parameterTypes) {
System.out.println(parameterType.getName());
System.out.println(parameterType.getSimpleName());
}
}
}
substring
public static void main(String[] args) {
UserDao userDao=new UserDaoImpl();
Class iface=userDao.getClass();
Method[] declaredMethods = iface.getDeclaredMethods();
String str="abcdefa";
System.out.println(str.lastIndexOf("a"));
str=str.substring(0,5);
System.out.println(str);
}