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想不明白。
刚学,对着视频一步一步来的,有点自闭了。求大神解惑是哪一步出错了,该如何解决呢。
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);进行类型转换
这个我明白,invoke返回的是有返回值的方法结果,具体类型是看方法的返回类型。但您可能没明白我的意思,我的问题是我生成的动态代理对象都是null,就是没有获取到动态代理类。
但我现在就只是想获得一个代理对象,invoke不做任何处理,而且我这个方法没有返回值,invoke返回null应该没有关系吧
@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,然后看看是报的什么错误
@Yougotmesinging:
不做处理也至少返回method.invoke(target);哦,至少返回目标方法的返回,不然你的代理类是没有任何用的
我返回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)
@Yougotmesinging: 循环有可能是递归调用了,看看你的target是目标代理对象还是jdk的对象造成的循环调用
@95的人:啊,感谢大佬,我犯了一个错误,我method.invoke()一直放的是代理对象。。。。晕了呀
@Yougotmesinging: 犯得错误越多,在排查之后理解的就越深,你如果把别人的代码拷贝过来能运行,并不能使你理解它,加油
@95的人: 嗯嗯,非常感谢