开发者社区 问答 正文

使用CGLib代理报java.lang.StackOverflowError问题?报错

package sun.testProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import org.junit.Test;

public class TestProxy {
	@Test
	public void testProxy() {
		Hello helloProxy = new HelloProxy();
		helloProxy.say("Sun");
	}

	@Test	//动态代理:要代理的类必须要有实现接口
	public void testDynamicProxy(){
		Hello hello = new HelloImpl();
		
		DynamicProxy dynamicProxy = new DynamicProxy(hello);
		Hello helloProxy = (Hello) Proxy.newProxyInstance(
				hello.getClass().getClassLoader(),
				hello.getClass().getInterfaces(), 
				dynamicProxy);
		helloProxy.say("Sun");
	}
	
	@Test	//测试封装Proxy获取方法后的情况
	public void testDynamicProxyPackage(){
		Hello hello = new HelloImpl();
		DynamicProxy dynamicProxy = new DynamicProxy(hello);
		Hello helloProxy = dynamicProxy.getProxy();
		helloProxy.say("Sun");
	}
	@Test	//方法级别的代理,不用实现接口
	public void testCGLibProxy(){
		CGLibProxy cgLibProxy = new CGLibProxy();
		HelloImpl helloProxy = cgLibProxy.getProxy(HelloImpl.class);
		helloProxy.say("Sun");
	}
}

/**
 * 接口
 * @author Administrator
 */
interface Hello{
	void say(String name);
}

/**
 * 实现类
 * @author Administrator
 */
class HelloImpl implements Hello{
	
	@Override
	public void say(String name) {
		System.out.println("Hello!" + name);
	}
}

//代理类(静态代理)
class HelloProxy implements Hello{

	private HelloImpl helloImpl;
	
	public HelloProxy() {
		helloImpl = new HelloImpl();
	}
	@Override
	public void say(String name) {
		before();
		helloImpl.say(name);
		after();
	}
	private void after() {
		System.out.println("After....");
	}
	private void before() {
		System.out.println("before...");
	}
}

//动态代理
class DynamicProxy implements InvocationHandler{

	private Object target;
	
	public DynamicProxy(Object target) {
		this.target = target;
	}
	@SuppressWarnings("unchecked")
	public <T> T getProxy(){
		return (T) Proxy.newProxyInstance(
				target.getClass().getClassLoader(), 
				target.getClass().getInterfaces(), 
				this);
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		before();
		Object result = method.invoke(target, args);
		method.invoke(target, args);
		after();
		return result;
	}
	private void after() {
		System.out.println("After....");
	}
	private void before() {
		System.out.println("before...");
	}
}

/**
 * CGLib代理
 * @author Administrator
 */
class CGLibProxy implements MethodInterceptor{

	@SuppressWarnings("unchecked")
	public <T> T getProxy(Class<T> cls){
		return (T) Enhancer.create(cls, this);
	}
	
	@Override
	public Object intercept(Object arg0, Method arg1, Object[] arg2,
			MethodProxy arg3) throws Throwable {
		before();
		Object result = arg3.invoke(arg0, arg2);
		after();
		return result;
	}
	private void after() {
		System.out.println("After....");
	}

	private void before() {
		System.out.println("before...");
	}
}

报错:

java.lang.StackOverflowError
	at sun.nio.cs.UTF_8$Encoder.encodeArrayLoop(UTF_8.java:446)
	at sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:517)
	at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:544)
	at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:252)
	at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:106)
	at java.io.OutputStreamWriter.write(OutputStreamWriter.java:190)
	at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:111)
	at java.io.PrintStream.write(PrintStream.java:476)
	at java.io.PrintStream.print(PrintStream.java:619)
	at java.io.PrintStream.println(PrintStream.java:756)
	at sun.testProxy.CGLibProxy.before(TestProxy.java:145)
	at sun.testProxy.CGLibProxy.intercept(TestProxy.java:135)
	at sun.testProxy.HelloImpl$$EnhancerByCGLIB$$7ac88992.say(<generated>)
	at sun.testProxy.HelloImpl$$FastClassByCGLIB$$bcd464de.invoke(<generated>)
	at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
	at sun.testProxy.CGLibProxy.intercept(TestProxy.java:136)
	at sun.testProxy.HelloImpl$$EnhancerByCGLIB$$7ac88992.say(<generated>)
	at sun.testProxy.HelloImpl$$FastClassByCGLIB$$bcd464de.invoke(<generated>)
	at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
	at sun.testProxy.CGLibProxy.intercept(TestProxy.java:136)
	at sun.testProxy.HelloImpl$$EnhancerByCGLIB$$7ac88992.say(<generated>)
	at sun.testProxy.HelloImpl$$FastClassByCGLIB$$bcd464de.invoke(<generated>)
	at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
	at sun.testProxy.CGLibProxy.intercept(TestProxy.java:136)

....

展开
收起
爱吃鱼的程序员 2020-06-22 14:38:36 983 分享 版权
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB

    使用invokeSuper方法,而不是invoke方法。

    ...@OverridepublicObjectintercept(Objectarg0,Methodarg1,Object[]arg2,MethodProxyarg3)throwsThrowable{before();//Objectresult=arg3.invoke(arg0,arg2);Objectresult=arg3.invokeSuper(arg0,arg2);after();returnresult;}... 给我最佳答案吧!哈哈!哎,还真是,看走眼了,多谢指点哦 把你的 CGLibProxy类 getProxy()方法更改为下面的内容试试 Enhancerenhancer=newEnhancer();//设置父类enhancer.setSuperclass(cls);//设置需要织入的逻辑enhancer.setCallback(this);return(T)enhancer.create();试了下,问题不在这儿,我是照着 @黄勇的博客《Proxy那些事儿》敲的,方法写错了,马虎大意了
    2020-06-22 14:38:53
    赞同 展开评论
问答分类:
问答地址: