第2次作业:反射与动态代理
1.编写一个Person类,生成class文件,请通过反射技术,为Person.class生成新的.java代码,java代码中的方法的方法体为空,即方法内部代码不用生成。请注意生成的java代码的格式。
2.请为第1题中Person类创建代理类 PersonProxy,PersonProxy的在代理Person类的所有setter方法时,把方法的调用时间、方法名称写入到文本文件中,每一行日志的格式为:
时间:2012-09-01 23:34:24;方法名称:setName;参数:张小平
3.请用动态代理技术完成第2题(答辩时要求结合Proxy.newProxyInstance的内部源码解释其实现过程)
package lib.Work2.Reflection01;
/**
* 1、(4分)请通过反射技术,为附件中的Person.class生成相应的.java代码,java代码中的方法的方法体为空,即方法内部代码不用生成。请注意生成的java代码的格式。
* 2、(3分)请为第1题中Person类创建代理类 PersonProxy,PersonProxy的在代理Person类的所有setter方法时,把方法的调用时间、方法名称写入到文本文件中,每一行日志的格式为:
* 时间:2012-09-01 23:34:24;方法名称:setName;参数:张小平
* 3、(3分)请用动态代理技术完成第2题
*/
public class Person implements Speakable {
private String name;//学生姓名
private String Gender;//性别
private String id;//身份证号
private String tel;//电话
public Person() {
}
public Person(String name, String Gender, String id, String tel) {
this.name = name;
this.Gender = Gender;
this.id = id;
this.tel = tel;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return Gender;
}
public void setGender(String Gender) {
this.Gender = Gender;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
@Override
public String toString() {
return "PersonRefection{" +
"name='" + name + '\'' +
", sex='" + Gender + '\'' +
", id='" + id + '\'' +
", tel='" + tel + '\'' +
'}';
}
@Override
public void speak(String message) {
System.out.println(message);
}
}
package lib.Work2.Reflection01;
//1、(4分)请通过反射技术,为附件中的Person.class生成相应的.java代码,java代码中的方法的方法体为空,即方法内部代码不用生成。请注意生成的java代码的格式。
//2、(3分)请为第1题中Person类创建代理类 PersonProxy,PersonProxy的在代理Person类的所有setter方法时,把方法的调用时间、方法名称写入到文本文件中,每一行日志的格式为:
// 时间:2012-09-01 23:34:24;方法名称:setName;参数:张小平
//3、(3分)请用动态代理技术完成第2题
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.*;
public class PersonReflection {
static String pathName = "D:\\javahmcxy\\javahqz12123020108\\SeniorJava\\src\\lib\\Work2\\Reflection01\\Person.java";
static FileOutputStream fos;
static {
try {
fos = new FileOutputStream(pathName);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
static Class clazz;
static {
try {
clazz = Class.forName("Person");
fos = new FileOutputStream(pathName);
} catch (ClassNotFoundException | FileNotFoundException e) {
e.printStackTrace();
}
}
public static void getPackage(String pathName) {
String packageName = clazz.getPackage().getName();
String writePackage = "package " + packageName + ";\n\n";
try {
fos.write(writePackage.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(final String[] args) throws NoSuchMethodException, IOException, ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException {
FileOutputStream fos = new FileOutputStream(pathName);
Class clazz = Class.forName("Person");
//获取类所在的包名
String packageName = clazz.getPackage().getName();
String writePackage = "package " + packageName + ";\n\n";
fos.write(writePackage.getBytes());
//获取类中的权限修饰符及类名并输出
String modifier = Modifier.toString(clazz.getModifiers());
String className = clazz.getSimpleName();
String writeClass = modifier + " class " + className + " {\n";
fos.write(writeClass.getBytes());
//获取类中所有的字段
Field[] fieldArray = clazz.getDeclaredFields();
for (Field f : fieldArray) {
String mod = Modifier.toString(f.getModifiers());
String type = f.getType().getSimpleName();
String name = f.getName();
String writeField = "\t" + mod + " " + type + " " + name + ";\n";
fos.write(writeField.getBytes());
}
fos.write("\n".getBytes());
//获取类中所有的构造方法
Constructor[] constructorArray = clazz.getConstructors();
for (Constructor c : constructorArray) {
String mod = Modifier.toString(c.getModifiers());
String writeConstructor = "\t" + mod + " " + className + "(";
//获取构造方法里面所有的参数
Class[] prams = c.getParameterTypes();
int count = 0;
for (Class cl : prams) {
String pramName = cl.getSimpleName();
writeConstructor += pramName + " args" + count;
if (count < prams.length - 1) {
writeConstructor += ", ";
}
count++;
}
writeConstructor += ") {}\n";
fos.write(writeConstructor.getBytes());
}
fos.write("\n".getBytes());
//获取类中所有的方法
Method[] methodArray = clazz.getDeclaredMethods();
for (Method m : methodArray) {
String mod = Modifier.toString(m.getModifiers());
String type = m.getReturnType().getSimpleName();
String name = m.getName();
String writeMethod = "\t" + mod + " " + type + " " + name + "(";
//与构造方法一样,获取方法里面所有的参数
Class[] prams = m.getParameterTypes();
int count = 0;
for (Class cl : prams) {
String pramName = cl.getSimpleName();
writeMethod += pramName + " args" + count;
if (count < prams.length - 1) {
writeMethod += ", ";
}
count++;
}
writeMethod += ") {\n";
if (type.equals("int") || type.equals("double")) {
writeMethod += "\t\treturn 0;\n";
} else if (type.equals("boolean")) {
writeMethod += "\t\treturn false;\n";
} else if (type.equals("void")) {
writeMethod += "";
} else {
writeMethod += "\t\treturn null;\n";
}
writeMethod += "\t}\n\n";
fos.write(writeMethod.getBytes());
}
fos.write("}".getBytes());
}
}
package lib.Work2.Reflection01;
import java.io.IOException;
public interface Speakable {
void speak(String message);
void setName(String args0) throws IOException;
void setTel(String args0) throws IOException;
void setGender(String args0) throws IOException;
void setId(String args0) throws IOException;
}
package lib.Work2.Proxy02;
/**
* 1、(4分)请通过反射技术,为附件中的Person.class生成相应的.java代码,java代码中的方法的方法体为空,即方法内部代码不用生成。请注意生成的java代码的格式。
* 2、(3分)请为第1题中Person类创建代理类 PersonProxy,PersonProxy的在代理Person类的所有setter方法时,把方法的调用时间、方法名称写入到文本文件中,每一行日志的格式为:
* 时间:2012-09-01 23:34:24;方法名称:setName;参数:张小平
* 3、(3分)请用动态代理技术完成第2题
*/
public class Person implements Speakable {
private String name;//学生姓名
private String Gender;//性别
private String id;//身份证号
private String tel;//电话
public Person() {
}
public Person(String name, String Gender, String id, String tel) {
this.name = name;
this.Gender = Gender;
this.id = id;
this.tel = tel;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return Gender;
}
public void setGender(String Gender) {
this.Gender = Gender;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
@Override
public String toString() {
return "PersonRefection{" +
"name='" + name + '\'' +
", sex='" + Gender + '\'' +
", id='" + id + '\'' +
", tel='" + tel + '\'' +
'}';
}
@Override
public void speak(String message) {
System.out.println(message);
}
}
package lib.Work2.Proxy02;
import lib.Work2.Reflection01.Person;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Calendar;
//2、(3分)请为第1题中Person类创建代理类 PersonProxy,PersonProxy的在代理Person类的所有setter方法时,把方法的调用时间、方法名称写入到文本文件中,每一行日志的格式为:
// 时间:2012-09-01 23:34:24;方法名称:setName;参数:张小平
public class PersonProxy implements Speakable {
Person person;
File file = new File("D:\\javahmcxy\\javahqz12123020108\\SeniorJava\\src\\lib\\Work2\\Proxy02\\PersonProxy.text");
public PersonProxy(Person person) {
this.person = person;
}
@Override
public void speak(String message) {
}
public void setName(String name) throws IOException {
WriteToText(file, "setName", name);
this.person.setName(name);
}
public void setGender(String Gender) throws IOException {
WriteToText(file, "setGender", Gender);
this.person.setGender(Gender);
}
public void setId(String id) throws IOException {
WriteToText(file, "setId", id);
this.person.setId(id);
}
public void setTel(String tel) throws IOException {
WriteToText(file, "setTel", tel);
this.person.setTel(tel);
}
public void WriteToText(File file, String MethodName, String parameter) throws IOException {
//如果文件不存在,就动态创建文件
if (!file.exists()) {
file.createNewFile();
}
final String writeDate = "时间:" + this.get_nowDate() + ";" + "方法名称:" + MethodName + ";参数:" + parameter;
try (FileWriter fw = new FileWriter(file, true)) {
//设置为:True,表示写入的时候追加数据
//回车并换行
fw.write(writeDate + "\r\n");
} catch (final IOException e) {
e.printStackTrace();
}
}
private String get_nowDate() {
Calendar D = Calendar.getInstance();
int year = 0;
int moth = 0;
int day = 0;
int hour = 0;
int minute = 0;
int second = 0;
year = D.get(Calendar.YEAR);
moth = D.get(Calendar.MONTH) + 1;
day = D.get(Calendar.DAY_OF_MONTH);
hour = D.get(Calendar.HOUR_OF_DAY);
minute = D.get(Calendar.MINUTE);
second = D.get(Calendar.SECOND);
return year + "-" + moth
+ "-" + day + " " + hour + ":"
+ minute + ":" + second;
}
}
package lib.Work2.Proxy02;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
class PersonRefection {
static String pathName = "D:\\javahmcxy\\javahqz12123020108\\SeniorJava\\src\\lib\\Work2\\Proxy02\\Person.java";
static FileOutputStream fos;
static {
try {
fos = new FileOutputStream(pathName);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
getPackage();
getClazz();
getField();
getConstructor();
getMethod();
}
/**
* 获取包名
*/
public static void getPackage() throws ClassNotFoundException {
Class<?> clazz = Class.forName("lib.Work2.Proxy02.Person");
String packageName = clazz.getPackage().getName();
String writePackage = "package " + packageName + ";\n\n";
try {
fos.write(writePackage.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取类中的权限修饰符及类名并输出
*/
public static void getClazz() throws IOException, ClassNotFoundException {
Class<?> clazz = Class.forName("lib.Work2.Proxy02.Person");
String modifier = Modifier.toString(clazz.getModifiers());
String className = clazz.getSimpleName();
String writeClass = modifier + " class " + className + " {\n";
fos.write(writeClass.getBytes());
}
/**
* 获取类中所有的字段
*/
public static void getField() throws IOException, ClassNotFoundException {
Class<?> clazz = Class.forName("lib.Work2.Proxy02.Person");
Field[] fieldArray = clazz.getDeclaredFields();
for (Field f : fieldArray) {
String mod = Modifier.toString(f.getModifiers());
String type = f.getType().getSimpleName();
String name = f.getName();
String writeField = "\t" + mod + " " + type + " " + name + ";\n";
fos.write(writeField.getBytes());
}
fos.write("\n".getBytes());
}
/**
* 获取类中所有的构造方法
*/
public static void getConstructor() throws IOException, ClassNotFoundException {
Class<?> clazz = Class.forName("lib.Work2.Proxy02.Person");
String className = clazz.getSimpleName();
Constructor[] constructorArray = clazz.getConstructors();
for (Constructor c : constructorArray) {
String mod = Modifier.toString(c.getModifiers());
String writeConstructor = "\t" + mod + " " + className + "(";
//获取构造方法里面所有的参数
Class[] prams = c.getParameterTypes();
int count = 0;
for (Class cl : prams) {
String pramName = cl.getSimpleName();
writeConstructor += pramName + " args" + count;
if (count < prams.length - 1) {
writeConstructor += ", ";
}
count++;
}
writeConstructor += ") {}\n";
fos.write(writeConstructor.getBytes());
}
fos.write("\n".getBytes());
}
/**
* 获取类中所有的方法
*/
public static void getMethod() throws IOException, ClassNotFoundException {
Class<?> clazz = Class.forName("lib.Work2.Proxy02.Person");
Method[] methodArray = clazz.getDeclaredMethods();
for (Method m : methodArray) {
String mod = Modifier.toString(m.getModifiers());
String type = m.getReturnType().getSimpleName();
String name = m.getName();
String writeMethod = "\t" + mod + " " + type + " " + name + "(";
//与构造方法一样,获取方法里面所有的参数
Class[] prams = m.getParameterTypes();
int count = 0;
for (Class cl : prams) {
String pramName = cl.getSimpleName();
writeMethod += pramName + " args" + count;
if (count < prams.length - 1) {
writeMethod += ", ";
}
count++;
}
writeMethod += ") {\n";
switch (type) {
case "int", "double" -> writeMethod += "\t\treturn 0;\n";
case "boolean" -> writeMethod += "\t\treturn false;\n";
case "void" -> writeMethod += "";
default -> writeMethod += "\t\treturn null;\n";
}
writeMethod += "\t}\n\n";
fos.write(writeMethod.getBytes());
}
fos.write("}".getBytes());
}
}
package lib.Work2.Proxy02;
import java.io.IOException;
public interface Speakable {
void speak(String message);
void setName(String args0) throws IOException;
void setTel(String args0) throws IOException;
void setGender(String args0) throws IOException;
void setId(String args0) throws IOException;
}
package lib.Work2.DynamicProxy03;
import java.io.IOException;
import java.lang.reflect.Proxy;
public class BootStrap {
public static void main(final String[] args) throws IOException {
//创建一个真实对象
Person person = new Person();
//创建一个动态代理对象
MyProxy myProxy = new MyProxy(person);
//获取被代理类的CLassLoader对象
ClassLoader loader = person.getClass().getClassLoader();
//动态构造一个代理对象
Speakable speakable = (Speakable) Proxy.newProxyInstance(loader,
new Class[]{Speakable.class},//接口对象数组,表示我们要给代理对象提供一个怎样的接口,如果提供了这样一组接口数组,就是声明了代理类实现了这些接口,代理类就可以调用接口中声明的所有方法。
myProxy);
speakable.setGender("man");
}
}
package lib.Work2.DynamicProxy03;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Calendar;
public class MyProxy implements InvocationHandler {
File file = new File("D:\\javahmcxy\\javahqz12123020108\\SeniorJava\\src\\lib\\Work2\\DynamicProxy03\\DynamicProxy.text");
private final Object proxied;
public MyProxy(Object proxied) {
this.proxied = proxied;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//proxy:代理类代理的真实代理对象
//method:我们要调用某个对象真实的方法的Method对象
//args:代理对象方法传递的参数
WriteToText(file, method.getName(), (String) args[0]);
method.invoke(this.proxied, args);
return null;
}
public void WriteToText(File file, String MethodName, String parameter) throws IOException {
//如果文件不存在,就动态创建文件
if (!file.exists()) {
file.createNewFile();
}
String writeDate = "时间:" + this.get_nowDate() + ";" + "方法名称:" + MethodName + ";参数:" + parameter;
try (FileWriter fw = new FileWriter(file, true)) {
//设置为:True,表示写入的时候追加数据
//回车并换行
fw.write(writeDate + "\r\n");
} catch (IOException e) {
e.printStackTrace();
}
}
private String get_nowDate() {
Calendar D = Calendar.getInstance();
int year = 0;
int moth = 0;
int day = 0;
int hour = 0;
int minute = 0;
int second = 0;
year = D.get(Calendar.YEAR);
moth = D.get(Calendar.MONTH) + 1;
day = D.get(Calendar.DAY_OF_MONTH);
hour = D.get(Calendar.HOUR_OF_DAY);
minute = D.get(Calendar.MINUTE);
second = D.get(Calendar.SECOND);
return year + "-" + moth
+ "-" + day + " " + hour + ":"
+ minute + ":" + second;
}
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package lib.Work2.DynamicProxy03;
public class Person implements Speakable {
private String name;
private String Gender;
private String id;
private String tel;
public Person() {
}
public Person(String name, String Gender, String id, String tel) {
this.name = name;
this.Gender = Gender;
this.id = id;
this.tel = tel;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return this.Gender;
}
public void setGender(String Gender) {
this.Gender = Gender;
}
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
public String getTel() {
return this.tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String toString() {
return "PersonRefection{name='" + this.name + "', sex='" + this.Gender + "', id='" + this.id + "', tel='" + this.tel + "'}";
}
public void speak(String message) {
System.out.println(message);
}
}
package lib.Work2.DynamicProxy03;
import java.io.IOException;
public interface Speakable {
void speak(String message);
void setName(String args0) throws IOException;
void setTel(String args0) throws IOException;
void setGender(String args0) throws IOException;
void setId(String args0) throws IOException;
}