java反射代理机制
2017-12-13 14:43
274 查看
package com.lin.text;
public class Person {
}
package com.lin.text;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.junit.Test;
public class PersonF {
}
:静态代理类和目标对象的类都是在编译期间确定下来的
:动态代理被代理的对象是一个实现抽象接口类,代理的对象是一个实现了InvocationHandler接口的类
静态代理实现:
package com.lin.text;
/**
* 静态代理模式
*/
//接口
interface Factory {
void show();
}
//被代理类
class FactoryImpl implements Factory {
}
//代理类,这里实现了接口,很明显他只能服务Factory这个接口
class ProxyFactory implements Factory {
}
public class TestSaticProxy {
}
动态代理:
package com.lin.text;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 动态代理
*/
//被代理类
interface Everything {
void show();
}
//代理类
class EverythingImpl implements Everything {
}
//创建动态代理类,注意动态代理都要实现一个InvocationHandler的接口
class MyInnvocationHandler implements InvocationHandler {
}
public class TestDynamicProxy {
}
public class Person {
public String name; private String sex; private int age; public void show(){ System.out.println("show::姓名:" + name + "性别:" +sex + "年龄:" + age); } public void shows(String name){ System.out.println("show::姓名:" + name + "性别:" +sex + "年龄:" + age); } @SuppressWarnings("unused") private void showp(){ System.out.println("showp::姓名:" + name + "性别:" +sex + "年龄:" + age); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }
}
package com.lin.text;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.junit.Test;
public class PersonF {
@Test public void main1() throws Exception { // 获取当前类的实例化对象 Class<Person> clazz = Person.class; // 1.创建clazz对应的运行时类Person,用的是clazz.newInstance() // 这里的clazz.newInstance()实际上是调用的是Person类的无参构造器 Person p = clazz.newInstance(); // 2.然后在调用,调用的时候先用clazz.getField(“属性名”)的方法来获取public作用域的属性,然后再往对象里面设值 Field nameF = clazz.getField("name"); nameF.set(p, "我奶妈贼六!"); // 3.获取private作用域的属性值方法比一样,用上面的方法获取不到 //首先应该获取声明的属性 Field sexF = clazz.getDeclaredField("sex"); Field ageF = clazz.getDeclaredField("age"); //将访问权限改为true sexF.setAccessible(true); ageF.setAccessible(true); sexF.set(p, "男"); ageF.set(p, 6); //3.通过反射调用运行类的方法,首先获取方法 Method showF = clazz.getMethod("show"); Method showpF = clazz.getMethod("showp"); //然后调用方法,没有形参的直接showF.invoke(p); showF.invoke(p); //没有设置就会报错 showpF.setAccessible(true); showpF.invoke(p); //调用有形参的方法,clazz.getMethod时需要指明参数的类型 Method showsF = clazz.getMethod("shows", String.class); //有形参的话showsF.invoke(p,形参);传入形参 showsF.invoke(p, "测试入参"); } /* * java.lang.Class是反射的源头 * 创建的类通过编译(javac.exe),生成对应点.class文件,之后我们使用的java.exe加载(JVM的类加载器) * .class文件,此。class文件加载到内存以后,就是一个运行时类,放在缓存中,那么这个运行时类本身就是一个Class类 * 1.每个运行时类只加载一次 * 2.有了class实例以后才能进行如下操作 * 1)创建对应的运行时类的对象 * 2)获取对应的运行时类的完整结构(属性、方法、构造器、内部类..) * 3)调用对应的运行时类的指定的结构(属性、方法、构造器) * 4)反射的应用:动态代理 */ @SuppressWarnings("rawtypes") @Test public void main2() throws Exception { //方法1 Class clazz = Person.class; System.out.println(clazz.getName()); System.out.println(String.class.getName()); //方法2.通过运行时类的对象获取 Person p = new Person(); Class clazz2 = p.getClass(); System.out.println(clazz2.getName()); //方法3.通过Class的静态方法 String classNme = "com.lin.text.Person";// Person路径 Class clazz3 = Class.forName(classNme); System.out.println(clazz3.getName()); //方法4.用类加载器 ClassLoader cl = this.getClass().getClassLoader(); Class clazz4 = cl.loadClass(classNme); System.out.println(clazz4); } //权限修饰符 变量类型 变量名 @SuppressWarnings("rawtypes") @Test public void main3() throws Exception { Class clazz = Person.class; Field[] fields = clazz.getDeclaredFields(); for(Field f: fields) { //1.获取每个属性的权限修饰符 int i = f.getModifiers(); //将权限的索引转变成对应的权限名字 String m = Modifier.toString(i); //2.获取每个属性的变量类型 String type = f.getType().getName(); //3.获取每个属性 的变量名 String name = f.getName(); System.out.println(m + "-" + type + "-" + name); } } //获取方法的一些属性 @SuppressWarnings("rawtypes") @Test public void main4() throws Exception { Class clazz = Person.class; //获取运行时类及其父类中public权限的方法 Method[] methods = clazz.getMethods(); for(Method m : methods) { System.out.println(m.getName() + ": " + Modifier.toString(m.getModifiers()) ); } //getDeclaredMethods是获取该类的中所有方法 Method[] methods2 = clazz.getDeclaredMethods(); for(Method m : methods2) { //获取注解 Annotation[] ann = m.getAnnotations(); for(Annotation a : ann) { System.out.println(a); } //获取形参列表 Class rt = m.getReturnType(); //获取异常类型 System.out.println("方法名:" + m.getName() + "-权限修饰符:" + Modifier.toString(m.getModifiers()) + "-注解:" + ann + "-返回值类型:" + rt); } }
}
Java中反射机制主要是应用在动态代理上
:静态代理类和目标对象的类都是在编译期间确定下来的
:动态代理被代理的对象是一个实现抽象接口类,代理的对象是一个实现了InvocationHandler接口的类
静态代理实现:
package com.lin.text;
/**
* 静态代理模式
*/
//接口
interface Factory {
void show();
}
//被代理类
class FactoryImpl implements Factory {
@Override public void show() { System.out.println("代理对象实现代理接口"); }
}
//代理类,这里实现了接口,很明显他只能服务Factory这个接口
class ProxyFactory implements Factory {
//声明的时候声明成Factory Factory f; //创建代理类,传入的是一个被代理类的对象 public ProxyFactory(Factory f) { this.f = f; } @Override public void show() { System.out.println("代理类执行"); f.show(); }
}
public class TestSaticProxy {
public static void main(String[] args) { //创建被代理的对象 FactoryImpl factory = new FactoryImpl(); //创建代理对象,因为是静态代理,所以这个代理只能为FactoryImpl这一个对象做代理, //当创建新的对象时,将又要创建代理对象,如果被代理的对象很多的话,就要创建很多的代理对象,很不方便 ProxyFactory pf = new ProxyFactory(factory); pf.show(); }
}
动态代理:
package com.lin.text;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 动态代理
*/
//被代理类
interface Everything {
void show();
}
//代理类
class EverythingImpl implements Everything {
@Override public void show() { System.out.println("代理类执行"); }
}
//创建动态代理类,注意动态代理都要实现一个InvocationHandler的接口
class MyInnvocationHandler implements InvocationHandler {
//实现了接口的被代理类的对象声明,这里由于是因为不能确定被代理类的对象的类,所以同一用Object类,在调用的时候 //根据被代理类的类型做适当的强转即可 Object obj; //给被代理对象实例化,返回一个代理类的对象 public Object blind(Object obj) { this.obj = obj; //三个参数意义(被代理类的类加载器, 被代理类实现的接口, 实现InvocationHandler的类,即动态代理的类) return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this); } //当通过代理类的对象发起对被重写的方法调用时,都会转换为如下的invoke方法的调用,即调用具体接口中的方法 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //调用被代理对象的方法,获取返回对象 Object rv = method.invoke(obj, args); return rv; }
}
public class TestDynamicProxy {
public static void main(String[] args) {
//被代理对象
EverythingImpl rs = new EverythingImpl();
//创建实现InnvocationHandler接口的动态代理类对象
MyInnvocationHandler mi = new MyInnvocationHandler();
//调用blind()方法,将被代理对象绑定到代理对象上,即设置代理对象
Object obj = mi.blind(rs);
//根据具体的被代理对象做强转,都是强转成对象的服务接口,这里的sub就是转成Subject接口对象
Everything sub = (Everything)obj;
//调用接口方法
sub.show();
FactoryImpl nike = new FactoryImpl();
obj = mi.blind(nike);
Factory pf = (Factory)obj;
pf.show();
}
}
相关文章推荐
- Java中的动态代理及反射机制
- 关于java的反射机制及动态代理
- 【转】java的反射机制中的动态代理代理(一)--简介
- JAVA的反射机制及代理机制
- 模拟实现Struts拦截器-蕴含着代理模式,AOP,工厂模式,依赖注入,Java 反射,动态构造等机制
- JAVA 反射机制与动态代理
- Java程序员从笨鸟到菜鸟之(八)反射和代理机制
- 【Java基础总结】-反射机制与代理机制
- java学习之路 之 反射机制综合练习题、动态代理实例
- java反射和代理机制
- 第8章 Java的反射机制、Java的代理机制、类加载
- Java程序员从笨鸟到菜鸟之(八)反射和代理机制
- JAVA反射和代理机制
- AOP:java动态代理+反射机制
- 利用Java的反射与代理机制实现IOC
- java反射中的动态代理机制(有实例)
- Java程序员从笨鸟到菜鸟之(八)反射和代理机制
- 【转】java的反射机制中的动态代理代理(二)--在远程方法调用中运用代理类
- java学习笔记13--反射机制与动态代理
- JAVA的反射机制与动态代理