Java放射语法,应用静态动态代理 1. 反射概念功能通过放射获取任何一个类加载到内存对象所属类、类的对象、成员变量方法、在动态代理中有用放射API:java.lang.Class : 代表一个类java.lang.reflect.Method: 代表类的方法java.lang.reflect.Field 代表类的成员变量java.lang.reflect.Constructor: 代表类的构造方法反射源头 java.lang.Class创建一个类通过java.exe编译以后对应.class,之后我们使用JVM加载器加载内存中此时.class类加载到内存以后是一个运行时类存在缓存区 每一个类都是一个java.lang.Class实例 这个实例可以获取运行时类的完整结构(属性、方法、父类、异常)、调用对应方法2. 反射基础API2.1.通过反射类中调用 属性、方法类Parent.javapackage com.denganzhi.bb; public class ParentT { }Person.javapackage com.denganzhi.bb; import java.io.File; import java.io.IOException; import java.io.Serializable; import javax.xml.ws.Action; import javax.xml.ws.soap.Addressing; Addressing public class Person extends ParentString implements Serializable{ public int age; private int sex; private String name; public int getAge() { return age; } public void setAge(int age) { this.age age; } public String getName() { return name; } public void setName(String name) { this.name name; } public Person(String name) { super(); this.name name; } Action public void dislay(String str) throws IOException{ //File filenew File(); //file.createNewFile(); System.out.println(我是display...:str); } private void dislay2(String str) { System.out.println(我是display...:private); } public Person() { super(); } public static void showDis(){ System.out.println(静态方法); } }代码区域package com.denganzhi.bb; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Properties; import org.junit.Test; public class Main { // 通过反射调用 属性、方法类 Test public void test1() throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, IOException{ // 方法1获取clazz 对应运行时候类 //Class clazz Person.class; // 方法2: // Person personnew Person(); // Class clazz person.getClass(); //方法3 //Class clazz Class.forName(com.denganzhi.bb.Person); // 方式4: 通过类加载器 ClassLoader classloaderthis.getClass().getClassLoader(); Class clazzclassloader.loadClass(com.denganzhi.bb.Person); // classloader加载文件,从当前包路径下加载资源文件, jdbc.properties在com.denganzhi.bb包下 //InputStream inputstreamclassloader.getSystemResourceAsStream(com\\denganzhi\\bb\\jdbc.properties); // 本地路径,项目工程下 InputStream inputstreamnew FileInputStream(new File(jdbc2.properties)); Properties propertiesnew Properties(); properties.load(inputstream); System.out.println(properties.getProperty(username)); Person p(Person) clazz.newInstance(); // 获取属性Field对象 /** * 1.public: * 相当于 p.age100 * 访问p.age */ Field ageField clazz.getField(age); ageField.set(p, 100); System.out.println(ageField.get(p)); /* * 2.private */ Field age2File clazz.getDeclaredField(sex); age2File.setAccessible(true); // 破坏private age2File.set(p, 1); System.out.println(age2File.get(p)); /*** * 3. 通过反射获取方法 * 方法名称、参数类型 */ Method m1 clazz.getMethod(dislay, String.class); m1.invoke(p, xiaoming); /** * private方法 */ Method m11 clazz.getDeclaredMethod(dislay2, String.class); m11.setAccessible(true); m11.invoke(p, xiaoming); /** * 静态方法 */ Method m2 clazz.getMethod(showDis); m2.invoke(Person.class); /** * 调用指定构器 */ Constructor consclazz.getDeclaredConstructor(String.class); Person newp(Person) cons.newInstance(小泽); System.out.println(newp.getName()); } }2.2.通过反射获取类中定义的属性// 获取属性结构 Test public void test2() throws ClassNotFoundException, InstantiationException, IllegalAccessException{ Class clazz Class.forName(com.denganzhi.bb.Person); // 获取运行时类的对象 Object obj clazz.newInstance(); // 调用Person类的无参构造函数,构造函数非private // 获取所有属性public Field[] fields clazz.getFields(); for (int i 0; i fields.length; i) { // 获取修饰符 public int k fields[i].getModifiers(); String kstrModifier.toString(k); System.out.println(修饰符:kstr); // 获取属性名类型 int Class type fields[i].getType(); System.out.println(type.getName()); System.out.println(fields[i]); } // 运行时候类本身的所有属性 Field[] fields2 clazz.getDeclaredFields(); for (int i 0; i fields2.length; i) { //System.out.println(fields2[i]); } }2.3. 通过反射获取类中定义的方法Test public void test3() throws ClassNotFoundException{ // 获取运行时候类的方法以及父类声明为public的方法 Class clazz Person.class; Method[] m1 clazz.getMethods(); for (int i 0; i m1.length; i) { // System.out.println(m1[i]); } // 本身声明的所有方法 Method[] m2 clazz.getDeclaredMethods(); for (int i 0; i m2.length; i) { System.out.println(); System.out.println(m2[i]); // 1. 注释 Annotation[] ann m2[i].getAnnotations(); for (Annotation annotation : ann) { System.out.println(annotation); } // 2. 权限修饰符 System.out.println(Modifier.toString(m2[i].getModifiers())); // 3. 返回值 Class? returnRypem2[i].getReturnType(); System.out.println(returnRype); // 4.方法名 System.out.println(m2[i].getName()); // 5. 形参列表 System.out.print((); Class[] params m2[i].getParameterTypes(); for (Class class1 : params) { System.out.print(class1.getName()); } System.out.println()); // 6. 异常类型 Class[] exceptionType m2[i].getExceptionTypes(); for (Class class1 : exceptionType) { System.out.println(class1.getName()); } } System.out.println(); // 9. 获取构造器 Constructor?[] consclazz.getDeclaredConstructors(); for (Constructor? constructor : cons) { System.out.println(构造器: constructor); } }2.4. 通过反射获取父类Test public void test4(){ Class clazz Person.class; System.out.println(clazz.getSuperclass());// 父类 System.out.println(clazz.getGenericSuperclass()); // 带泛型父类 ParameterizedType param (ParameterizedType)clazz.getGenericSuperclass(); Type[] ars param.getActualTypeArguments(); // 泛型类型 System.out.println((Class)ars[0]); // 获取父类的方泛型在jdbc获取basedao父类然后实例化对象 // 获取实现接口 Class[] interfaceClass clazz.getInterfaces(); for (Class class1 : interfaceClass) { System.out.println(class1); } // 获取所在的包 System.out.println(clazz.getPackage()); // 类获取类的注解 Annotation[] anns clazz.getAnnotations(); for (Annotation annotation : anns) { System.out.println(annotation); } }3. 反射应用3.1. 静态代理传入实例对象代理类中调用方法【只能买房】package com.denganzhi.dongtai; //静态代理模式 //接口 interface ClothFactory{ void productCloth(); } //被代理类 class NikeClothFactory implements ClothFactory{ Override public void productCloth() { System.out.println(Nike工厂生产一批衣服); } } //代理类 class ProxyFactory implements ClothFactory{ ClothFactory cf; //创建代理类的对象时实际传入一个被代理类的对象 public ProxyFactory(ClothFactory cf){ this.cf cf; } Override public void productCloth() { System.out.println(代理类开始执行收代理费$1000); cf.productCloth(); } } public class TestClothProduct { public static void main(String[] args) { NikeClothFactory nike new NikeClothFactory();//创建被代理类的对象 ProxyFactory proxy new ProxyFactory(nike);//创建代理类的对象,传入被代理类对象即可 proxy.productCloth(); // 调用代理类方法 } }3.2. 动态代理【可以在代理中买房、买车】package com.denganzhi.dongtai; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; //动态代理的使用体会反射是动态语言的关键 interface Subject { void action(); } // 被代理类1 class RealSubject implements Subject { public void action() { System.out.println(我要买房子); } } class BuyCar implements Subject { public void action() { System.out.println(我要买车子); } } class MyInvocationHandler implements InvocationHandler { Object obj;// 实现了接口的被代理类的对象的声明 // ①给被代理的对象实例化②返回一个代理类的对象 public Object blind(Object obj) { this.obj obj; return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj .getClass().getInterfaces(), this); } //当通过代理类的对象发起对被重写的方法的调用时都会转换为对如下的invoke方法的调用 Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //method方法的返回值时returnVal Object returnVal method.invoke(obj, args); return returnVal; } } public class TestProxy { public static void main(String[] args) { //1.被代理类的对象 RealSubject real new RealSubject(); BuyCar buycar new BuyCar(); //2.创建一个实现了InvacationHandler接口的类的对象 MyInvocationHandler handler new MyInvocationHandler(); //3.调用blind()方法动态的返回一个同样实现了real所在类实现的接口Subject的代理类的对象。 // 被代理类1买房 Object obj handler.blind(real); Subject sub (Subject)obj;//此时sub就是代理类的对象 sub.action();//转到对InvacationHandler接口的实现类的invoke()方法的调用 // 被代理类2买车 Object obj1 handler.blind(buycar); Subject sub1 (Subject)obj1;//此时sub就是代理类的对象 sub1.action(); } }3.3.动态代理实际应用AOP 【打印日志例子】package com.denganzhi.dongtai; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; interface Human { void info(); void fly(); } // 被代理类 class SuperMan implements Human { public void info() { System.out.println(打印日志中1); } public void fly() { System.out.println(打印日志中2); } } class HumanUtil { public void method1() { System.out.println(插入的方法一打印日志前); } public void method2() { System.out.println(插入的方法二打印日志后); } } class MyInvocationHandler implements InvocationHandler { Object obj;// 被代理类对象的声明 public void setObject(Object obj) { this.obj obj; } Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { HumanUtil h new HumanUtil(); h.method1(); Object returnVal method.invoke(obj, args); h.method2(); return returnVal; } } class MyProxy { // 动态的创建一个代理类的对象 public static Object getProxyInstance(Object obj) { MyInvocationHandler handler new MyInvocationHandler(); handler.setObject(obj); return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj .getClass().getInterfaces(), handler); } } public class TestAOP { public static void main(String[] args) { SuperMan man new SuperMan();//创建一个被代理类的对象 Object obj MyProxy.getProxyInstance(man);//返回一个代理类的对象 Human hu (Human)obj; hu.info();//通过代理类的对象调用重写的抽象方法 hu.fly(); } }4.类载器层次结构Bootstap Classloader : 引导类加载器用于加载jdk中api类 无法通过api获取↑ 父类Extension Classloader : 扩展类加载器用于加载jre/lib/ext目录下jar包或者第三方jar包↑ 父类System Classloader: 系统类加载器用于加载用户写的类Class class1 Class.forName(com.dengnzhi.test.Student);Student student (Student) class1.newInstance();System.out.println(系统类加载器:class1.getClassLoader());System.out.println(扩张类加载器:class1.getClassLoader().getParent());System.out.println(引导类加载器:class1.getClassLoader().getParent().getParent());系统类加载器:sun.misc.Launcher$AppClassLoader73d16e93扩张类加载器:sun.misc.Launcher$ExtClassLoader6d06d69c引导类加载器:null