动态代理模式+tostring方法
2017-10-21 14:53
211 查看
package com.te;
public interface Interfa {
public String retu();
public int re(Integer a,Integer b);
}
package com.te; public class Realizeclass implements Interfa{ @Override public String retu() { // TODO Auto-generated method stub return "ABC"; } @Override public int re(Integer a, Integer b) { // TODO Auto-generated method stub return a+b; } }
package com.te; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class Maind { public static void main(String[] args) { // TODO Auto-generated method stub Interfa realize=new Realizeclass(); Object object=Proxy.newProxyInstance(//代理类 realize.getClass().getClassLoader(), //目标类 realize.getClass().getInterfaces(),//接口 new InvocationHandler() {//内部类实现方法拦截 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub Object result=method.invoke(realize, args); if(args!=null&&args.length>0) { System.out.println(args[0]+"dddd"+args[1]); } if(result instanceof String) { return result.toString().toLowerCase(); }else if(result instanceof Integer) { return ((int)result%10); } return result.toString(); } } ); Interfa fian=(Interfa)object; String result=fian.retu();//调用目标方法后被拦截 int c=fian.re(3, 4);//调用目标方法后被拦截 System.out.println(result); System.out.println(c); } }
toString方法是Object类里的一个实例方法,所有Java类都是object类的子类,因此所有Java对象都具有toString方法。
不仅如此,所有Java对象都可以和字符串进行连接运算,当Java对象和字符串进行连接运算时,系统自动调用Java对象toString()方法返回值和字符串进行连接运算下面代码效果相同
String pStr=p+””;
StringpStr=p.toString()+””;
toString()方法是一个非常特殊的方法,是一个“自我描述”方法,该方法通常用于实现当程序员直接打印该对象时,系统将会输出该对象的“自我描述”信息,用以告诉外界该对象具有的状态信息。
Object类提供的toString()方法总是返回该对象实现类的”类名+@+hashCode”值,这个返回值不能真正实现“自我描述”功能,因此我们可以重写object的toString()方法。
把上面的方式再分清楚一点
package com.te;
public interface Interfa {
public String retu();
public int re(Integer a,Integer b);
}
package com.te; public class Realizeclass implements Interfa{ @Override public String retu() { // TODO Auto-generated method stub return "ABC"; } @Override public int re(Integer a, Integer b) { // TODO Auto-generated method stub return a+b; } }
package com.te;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class Ge implements InvocationHandler{
Interfa realize=null;
public Object Gere(Interfa realize) {
this.realize=realize;
return this;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
Object result=null;
if(method!=null) {
result=method.invoke(realize, args);
}
if(args!=null&&args.length>0) {
System.out.println(args[0]+"dddd"+args[1]);
}
if(result!=null&&result instanceof String) {
return result.toString().toLowerCase();
}else if(result!=null&&result instanceof Integer) {
return ((int)result%10);
}
return result.toString();
}
}
package com.te; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class Maind { public static void main(String[] args) { // TODO Auto-generated method stub Interfa impl=new Realizeclass(); InvocationHandler fian=(InvocationHandler) new Ge().Gere(impl); Object obj = Proxy.newProxyInstance(impl.getClass().getClassLoader(), impl.getClass().getInterfaces(), fian); String result=null; int c=0; if(obj!=null) { result=((Interfa) obj).retu();//调用目标方法后被拦截 c=((Interfa) obj).re(3, 4);//调用目标方法后被拦截 } System.out.println(result); System.out.println(c); } }
第二种:没有接口通过继承来实现
package com.hanwei.agentclass; import java.lang.reflect.Method; import com.hanwei.target.impl.Uplowerimpl; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; //代理类增强目标类方法 public class Agentcalss implements MethodInterceptor{ private Uplowerimpl target; //Agentcalss A类 public Uplowerimpl agentcalss() { //创建加强对象 Enhancer enhance=new Enhancer();//B类 //制定目标对象,就是父类 enhance.setSuperclass(Uplowerimpl.class); //设置回调对象 enhance.setCallback(this);//A类中调用B类方法 A类中传输A类的对象去B类供B类调用A类方法 return (Uplowerimpl)enhance.create(); } 4000 public Agentcalss() { this.target = new Uplowerimpl(); } @Override public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {//回调方法 // TODO Auto-generated method stub System.out.println("调用translower方法之前输出"); Object result=arg1.invoke(target, arg2); System.out.println("result:"+result); if(result!=null) { result=((String)result).toLowerCase();//增强方法translower } return result; } public static void main(String[] args) throws InterruptedException { Uplowerimpl animalProxy=new Agentcalss().agentcalss();//A类调用B类中的方法 String result=animalProxy.translower();//B类中的方法又调用A类intercept,所以intercept是回调方法 System.out.println("result:"+result);//这里有调用tostring(),Sytem.out.println中只能输出字符串的; } }
package com.hanwei.target.impl; import java.lang.reflect.Method; import com.hanwei.agentclass.Agentcalss; import com.hanwei.target.Uplower; //目标实现类 public class Uplowerimpl{ public String translower() { // TODO Auto-generated method stub String a="a"; System.out.println("我是目标实现类中的方法1"); return "ABC"; } public String transupper() { // TODO Auto-generated method stub String b="b"; System.out.println("我是目标实现类中的方法2"); return "abc"; } }
1.这里注意用的asm包和cglib包要统一是spring或者是hibernate的
否则会出现
Caused by: java.lang.NoClassDefFoundError: org/objectweb/asm/Type
增强方法种如何调用了非final方法会出现栈溢出的无线死循环
第三种有接口
package com.enhance; import com.enhance.impl.DogImpl; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub Animal imple=new Agent().target(); System.out.println(imple.run()); } }
package com.enhance; import java.lang.reflect.Method; import com.enhance.impl.DogImpl; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class Agent implements MethodInterceptor{ private Animal target; public DogImpl target() { Enhancer enhance=new Enhancer(); //制定目标对象,就是父类 enhance.setSuperclass(DogImpl.class); //指定回调对象 enhance.setCallback(this); return (DogImpl)enhance.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { target = new DogImpl(); Object result=null; result=method.invoke(target, args); if(result!=null) { result=((String)result).toLowerCase(); } return result; } }
package com.enhance.impl; import com.enhance.Animal; public class DogImpl implements Animal { @Override public String run() { // TODO Auto-generated method stub System.out.println("狗会跑"); return "ABC"; } }
package com.enhance; public interface Animal { public String run(); }
相关文章推荐
- 代理模式之Java动态代理实现方法
- 【设计模式】【动态代理,在方法前和方法后加事务,AOP】
- java 动态代理(模式) InvocationHandler(为类中方法执行前或后添加内容)
- java 动态代理(模式) InvocationHandler(为类中方法执行前或后添加内容)
- 利用动态代理模式来增强方法
- JDK动态代理中的问题——调用proxy的toString方法引起的栈溢出
- 代理方法动态代理模式封装事务详解
- 为什么SpringAOP使用JDK动态代理时好像没有代理Object.[equals()、hashCode()、toString()]这三个方法
- Android设计模式之动态代理,实现方法拦截功能
- 【设计模式】动态代理,附使用方法
- 代理模式——动态代理和模板方法那点事
- 关于动态代理---模板方法模式,工厂模式,依赖倒转
- 方法调用黑马程序员_代理模式之动态代理
- 增强 修改对象的集中方法(继承、装饰者模式、动态代理)
- Cglib方法实现动态代理
- 设计模式之动态代理
- 设计模式之静态代理&动态代理
- 动态代理 和 装饰模式的 一些思考
- 代理模式【介绍、静态代理、动态代理、入门、应用】
- 静态代理和动态模式