java反射代理技术
2013-08-30 03:09
288 查看
静态代理
package senssic.demo; /** * 静态代理 * * @author Administrator * */ interface AFace {// 接口 public void say(); } class BClass implements AFace {// 实际类 @Override public void say() { System.out.println("hello word!"); } } class PBClass implements AFace {// 代理类 private final BClass bClass; public PBClass(BClass bClass) { this.bClass = bClass; } @Override public void say() { // TODO Auto-generated method stub System.out.println("运行实际类方法前可发生的事情…………"); this.bClass.say(); System.out.println("运行实际类方法后可发生的事情…………"); } } public class PoxyClass { public static void main(String[] args) { AFace aFace = new PBClass(new BClass()); aFace.say(); } }
缺点:
一个代理类只能为一个接口服务,所以我们接下来使用动态代理
jdk的动态
package senssic.demo; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * 动态代理 * * @param args */ interface BFace {// 接口 public void say(); } class BClass implements BFace {// 真实类 @Override public void say() { System.out.println("hello word!"); } } class DPClass implements InvocationHandler {// 动态代理类必须实现InvocationHandler接口并实现invoke方法确定实现的类 private Object object; public Object bind(Object object) { this.object = object; return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this);// 使用反射代理类Proxy实例化代理的接口(必须绑定接口),如果想代理没有接口的类需要使用cglib包 } @Override public Object invoke(Object proxy, Method method, Object[] args)// 调用对应的方法 throws Throwable { System.out.println("运行实际类方法前可发生的事情…………"); Object temp = method.invoke(this.object, args); System.out.println("运行实际类方法后可发生的事情…………"); return temp; } } public class DPoxyClass { public static void main(String[] args) { BFace bFace = (BFace) new DPClass().bind(new BClass()); bFace.say(); } }
优点:可以动态的代理,不限于接口的类型
缺点:必须绑定接口,即代理的类必须要实现接口,如果代理未实现接口的类我们需要apache的cglib包
外包的动态代理
下载地址: http://cglib.sourceforge.net/package senssic.demo; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; class CClass {// 实际类 public void say() { System.out.println("hello word!"); } } class CPlass implements MethodInterceptor {// 代理类,必须实现MenthodInterceptor接口通过反射调用实际方法 private Object object; public Object bind(Object object) {// 绑定操作设置对应的实际类 this.object = object; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.object.getClass()); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object obj, Method method, Object[] objects, MethodProxy proxy) throws Throwable { System.out.println("运行实际类方法前可发生的事情…………"); Object temp = proxy.invokeSuper(obj, objects);// 反射调用实际类方法 System.out.println("运行实际类方法后可发生的事情…………"); return temp; } } public class CPClass { public static void main(String[] args) { CPlass cPlass = new CPlass(); CClass cClass = (CClass) cPlass.bind(new CClass()); cClass.say(); } }Cglib动态代理
JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
仿spring原理的实现
package senssic.demo; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Properties; interface DFace {//实际类接口 public void say(); } class DClass implements DFace {//实际类,因为是jdk动态代理所以必须有实现接口 @Override public void say() { System.out.println("hello word!"); } } class BeanFactory {// bean工厂 Properties pros = new Properties(); public BeanFactory(InputStream ips) { try { pros.load(ips); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public Object getBean(String name) { String className = pros.getProperty(name); Class cla = null; Object bean = null; try { cla = Class.forName(className); bean = cla.newInstance(); if (bean instanceof ProxyFactoryBean) { ProxyFactoryBean pFactoryBean = (ProxyFactoryBean) bean; Adivce advice = (Adivce) Class.forName( pros.getProperty(name + ".advice")).newInstance(); Object target = Class.forName( pros.getProperty(name + ".target")).newInstance(); pFactoryBean.setAdvice(advice); pFactoryBean.setTarget(target); Object proxy = pFactoryBean.getProxy(); return proxy; } } catch (Exception e) { // TODO: handle exception } return bean; } } class ProxyFactoryBean {//业务处理类 private Adivce advice; private Object target; public Adivce getAdvice() { return advice; } public void setAdvice(Adivce advice) { this.advice = advice; } public Object getTarget() { return target; } public void setTarget(Object target) { this.target = target; } public Object getProxy() { Object temp = Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass() .getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object obj, Method method, Object[] objects) throws Throwable { advice.before(); Object object = method.invoke(target, objects); advice.after(); return object; } }); return temp; } } class Adivce { public void before() { System.out.println("运行实际类方法前可发生的事情…………"); } public void after() { System.out.println("运行实际类方法后可发生的事情…………"); } } public class SClass { public static void main(String[] args) { InputStream ips = SClass.class.getResourceAsStream("config.properties"); DFace bean = (DFace) new BeanFactory(ips).getBean("xxx");//动态代理类只能被转换为对应的接口,不能转换为实现类 bean.say(); } }
配置文件为:在同一目录下,文件名:config.properties
#xxx=java.util.ArrayList
xxx=senssic.demo.ProxyFactoryBean
xxx.advice=senssic.demo.Adivce
xxx.target=senssic.demo.DClass
运行结果:
运行实际类方法前可发生的事情…………
hello word!
运行实际类方法后可发生的事情…………
相关文章推荐
- 黑马程序员-----java基础二十一(java之反射技术应用(代理))
- JavaSE(10):Java反射技术及动态代理
- Java 反射与代理技术及应用解读
- 【Java核心技术】类型信息(Class对象 反射 动态代理)
- JAVA反射_代理
- java动态代理,结合hadoop技术内幕中的例子
- 黑马程序员-Java基础学习-反射技术
- Java动态代理与反射详解
- java中的反射和代理、object类
- 黑马学习笔记_Java 反射技术
- 15. JAVA 反射机制 Part 2(动态代理、类的生命周期、工厂设计模式) ----- 学习笔记
- Android 开源项目源码解析 -->公共技术点之 Java 反射 Reflection(十六)
- JAVA AOP编程之动态代理技术
- JDBC_利用Java反射技术将查询结果封装为对象
- Android系统原理与源码分析(1):利用Java反射技术阻止通过按钮关闭对话框
- 利用Java的反射与代理实现IOC模式
- Java中反射、静态代理、动态代理
- Java核心技术点之动态代理
- java反射技术
- 杂谈下java的反射(反射,动态代理)