首页 新闻 赞助 找找看

JDK动态代理和cglib动态代理最后获取的代理对象object都为null的问题

0
悬赏园豆:200 [已关闭问题] 关闭于 2021-01-08 10:21

1、JDK动态代理获取代理对象

接口 如下:

package com.ecut.mapper;

public interface ReactHouse {
public void reathouse();
}

实现类:

package com.ecut.mapper.impl;

import com.ecut.mapper.ReactHouse;

public class UserImpl implements ReactHouse{

@Override
public void reathouse() {
	System.out.println("我要买房子");
	
}

}

jdk动态代理获取类:

package com.ecut.service;

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

public class GetProxy {

private Object target;

public GetProxy(Object target) {
	this.target = target;
}

public  Object getProxy() {
	
	
	
	ClassLoader loader = this.getClass().getClassLoader();
	
	Class[] interfaces = target.getClass().getInterfaces();
	
	InvocationHandler  h = new InvocationHandler () {

		@Override
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			
			return null;
		}
		
	};
	Object agency = Proxy.newProxyInstance(loader, interfaces, h);
	return agency;
}

}

运行类:
package com.ecut.test;

import com.ecut.mapper.ReactHouse;
import com.ecut.mapper.impl.UserImpl;
import com.ecut.service.GetProxy;

public class Starter {
public static void main(String[] args) {

	ReactHouse target = new UserImpl();
	GetProxy getProxy = new GetProxy(target);
	ReactHouse reactHouse = (ReactHouse)getProxy.getProxy();
	reactHouse.reathouse();

// UserImpl userImpl = new UserImpl();
// CglibProxy proxy = new CglibProxy(userImpl);
// UserImpl user = (UserImpl)proxy.getProxy();
// user.reathouse();

}

}
从这获取的 reactHouse 对象为null ,问题所在我找到了但不知道如何解决
原因是获取的安全接口为null。。。System.getSecurityManager() == null

2、cglib动态代理获取代理对象

代理对象获取类:
package com.ecut.service;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

public class CglibProxy {
private Object target;

public CglibProxy(Object target) {
	this.target = target;
}

public Object getProxy() {
	
	Enhancer enhancer = new Enhancer();
	
	enhancer.setSuperclass(target.getClass());
	
	MethodInterceptor methodInterceptor = new MethodInterceptor() {

		@Override
		public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
			System.out.println("intercept..");
			
			return null;
		}
		
	};
	enhancer.setCallback(methodInterceptor);
	Object object = enhancer.create();
	return object;
}

}

运行:

UserImpl userImpl = new UserImpl();
CglibProxy proxy = new CglibProxy(userImpl);
UserImpl user = (UserImpl)proxy.getProxy();
user.reathouse();

运行结果:
intercept..
intercept..
null

获取的user 对象依旧为null想不明白。
刚学,对着视频一步一步来的,有点自闭了。求大神解惑是哪一步出错了,该如何解决呢。

Yougotmesinging的主页 Yougotmesinging | 初学一级 | 园豆:188
提问于:2021-01-08 10:05
< >
分享
所有回答(1)
0

jdk生成代理对象的时候除了用户自定义的方法,还会有隐式的,比如也会生成Object的方法toString(),hashCode(),equals()方法,实现InvocationHandler()接口是为了对原有的方法调用时做增强处理,返回的结果就是对方法调用时应当返回的结果,实际返回类型不同方法是不同的,所以是用的Object,你应该在invok方法里做处理,不应该返回null,可以通过System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");生成代理的对象
可以看到生成的代理类的每个方法都会调用return (String)super.h.invoke(this, m30, (Object[])null);进行类型转换

95的人 | 园豆:330 (菜鸟二级) | 2021-01-08 10:32

这个我明白,invoke返回的是有返回值的方法结果,具体类型是看方法的返回类型。但您可能没明白我的意思,我的问题是我生成的动态代理对象都是null,就是没有获取到动态代理类。

支持(0) 反对(0) Yougotmesinging | 园豆:188 (初学一级) | 2021-01-08 10:41

但我现在就只是想获得一个代理对象,invoke不做任何处理,而且我这个方法没有返回值,invoke返回null应该没有关系吧

支持(0) 反对(0) Yougotmesinging | 园豆:188 (初学一级) | 2021-01-08 10:45

@Yougotmesinging:

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

		return null;
	}

改成
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

		return new Object();;
	}

看看还是不是null,然后看看是报的什么错误

支持(0) 反对(0) 95的人 | 园豆:330 (菜鸟二级) | 2021-01-08 10:47

@Yougotmesinging:
不做处理也至少返回method.invoke(target);哦,至少返回目标方法的返回,不然你的代理类是没有任何用的

支持(0) 反对(0) 95的人 | 园豆:330 (菜鸟二级) | 2021-01-08 10:54

我返回method.invoke(target)现在一直报循环报这个错不知道为啥
at java.base/jdk.internal.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at com.ecut.service.GetProxy$1.invoke(GetProxy.java:28)
at com.sun.proxy.$Proxy0.toString(Unknown Source)

支持(0) 反对(0) Yougotmesinging | 园豆:188 (初学一级) | 2021-01-08 11:11

@Yougotmesinging: 循环有可能是递归调用了,看看你的target是目标代理对象还是jdk的对象造成的循环调用

支持(0) 反对(0) 95的人 | 园豆:330 (菜鸟二级) | 2021-01-08 11:24

@95的人:啊,感谢大佬,我犯了一个错误,我method.invoke()一直放的是代理对象。。。。晕了呀

支持(0) 反对(0) Yougotmesinging | 园豆:188 (初学一级) | 2021-01-08 11:29

@Yougotmesinging: 犯得错误越多,在排查之后理解的就越深,你如果把别人的代码拷贝过来能运行,并不能使你理解它,加油

支持(0) 反对(0) 95的人 | 园豆:330 (菜鸟二级) | 2021-01-08 11:33

@95的人: 嗯嗯,非常感谢

支持(0) 反对(0) Yougotmesinging | 园豆:188 (初学一级) | 2021-01-08 11:37
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册