Java 如何将CGLib代理转换为字节伙伴
我正在努力将CGLib使用的代理转换为BB。我已经很容易地实现了声明的方法拦截,但无法根据需要扩展对象。在CGLib中,我使用接口和拦截器。以下是我的CGLib代理代码:Java 如何将CGLib代理转换为字节伙伴,java,byte-buddy,Java,Byte Buddy,我正在努力将CGLib使用的代理转换为BB。我已经很容易地实现了声明的方法拦截,但无法根据需要扩展对象。在CGLib中,我使用接口和拦截器。以下是我的CGLib代理代码: public interface IObjectProxy { public OrientVertex ___getVertex(); public String ___getRid(); public void ___setVertex(OrientVertex v); public Ori
public interface IObjectProxy {
public OrientVertex ___getVertex();
public String ___getRid();
public void ___setVertex(OrientVertex v);
public OrientVertex ___getEdge();
public void ___setEdge(OrientEdge v);
public Class<?> ___getBaseClass();
public Object ___getProxiObject();
public boolean ___isDirty() ;
public void ___removeDirtyMark();
public void ___commit();
public void ___rollback();
}
public class ObjectProxyFactory implements MethodInterceptor, IObjectProxy {
private final static Logger LOGGER = Logger.getLogger(ObjectProxyFactory.class.getName());
// the real object
private Object ___proxyObject;
private Class<?> ___baseClass;
// Vértice desde el que se obtiene el objeto.
// private OrientVertex baseVertex;
private OrientElement ___baseElement;
private SessionManager ___sm;
private boolean ___dirty = false;
// constructor - the supplied parameter is an
// object whose proxy we would like to create
private ObjectProxyFactory(Object obj, OrientElement e, SessionManager sm) {
this.___baseClass = obj.getClass();
this.___baseElement = e;
this.___sm = sm;
}
// this method will be called each time
// when the object proxy calls any of its methods
@Override
public Object intercept(Object o,
Method method,
Object[] args,
MethodProxy methodProxy) throws Throwable {
// response object
Object res = null;
// BEFORE
// measure the current time
// long time1 = System.currentTimeMillis();
// System.out.println("intercepted: " + method.getName());
// modificar el llamado
switch (method.getName()) {
case "___getVertex":
res = this.___getVertex();
break;
case "___getRid":
res = this.___getRid();
break;
case "___getProxiObject":
res = this.___getProxiObject();
break;
case "___getBaseClass":
res = this.___getBaseClass();
break;
case "___isDirty":
res = this.___isDirty();
break;
case "___removeDirtyMark":
this.___removeDirtyMark();
break;
case "___commit":
this.___commit();
break;
default:
// invoke the method on the real object with the given params
// res = methodProxy.invoke(realObj, args);
res = methodProxy.invokeSuper(o, args);
// verificar si hay diferencias entre los objetos.
this.commitObjectChange();
break;
}
// AFTER
// print how long it took to execute the method on the proxified object
// System.out.println("Took: " + (System.currentTimeMillis() - time1) + " ms");
// return the result
return res;
}
private void setProxyObject(Object po) {
this.___proxyObject = po;
}
public static <T> T createProxy(T obj, OrientElement ov, SessionManager sm) {
// this is the main cglib api entry-point
// this object will 'enhance' (in terms of CGLIB) with new capabilities
// one can treat this class as a 'Builder' for the dynamic proxy
Enhancer e = new Enhancer();
// the class will extend from the real class
e.setSuperclass(obj.getClass());
// we have to declare the interceptor - the class whose 'intercept'
// will be called when any method of the proxified object is called.
ObjectProxyFactory opf = new ObjectProxyFactory(obj,ov, sm);
e.setCallback(opf);
e.setInterfaces(new Class[]{IObjectProxy.class});
// now the enhancer is configured and we'll create the proxified object
T proxifiedObj = (T) e.create();
opf.setProxyObject(proxifiedObj);
// the object is ready to be used - return it
return proxifiedObj;
}
/**
* retorna el vértice asociado a este proxi o null en caso que no exista uno.
*
* @return
*/
@Override
public OrientVertex ___getVertex() {
if (this.___baseElement.getElementType().equals("Vertex")) {
return (OrientVertex) this.___baseElement;
} else {
return null;
}
}
/**
* retorna el vértice asociado a este proxi o null en caso que no exista uno.
*
* @return
*/
@Override
public String ___getRid() {
if (this.___baseElement != null) {
return this.___baseElement.getId().toString();
} else {
return null;
}
}
/**
*
* establece el elemento base como un vértice.
*
* @param v
*/
@Override
public void ___setVertex(OrientVertex v) {
this.___baseElement = v;
}
/**
* retorna el vértice asociado a este proxi o null en caso que no exista uno.
*
* @return
*/
@Override
public OrientVertex ___getEdge() {
if (this.___baseElement.getElementType().equals("Edge")) {
return (OrientVertex) this.___baseElement;
} else {
return null;
}
}
/**
*
* establece el elemento base como un vértice.
*
* @param v
*/
@Override
public void ___setEdge(OrientEdge e) {
this.___baseElement = e;
}
@Override
public Object ___getProxiObject() {
return this.___proxyObject;
}
@Override
public Class<?> ___getBaseClass() {
return this.___baseClass;
}
private void commitObjectChange() {
LOGGER.log(Level.INFO, "iniciando commit interno....");
// si ya estaba marcado como dirty no volver a procesarlo.
if (!___dirty) {
....
....
lot's of code here
...
...
if (this.___dirty) {
// agregarlo a la lista de dirty para procesarlo luego
this.___sm.setAsDirty(this);
System.out.println("Objeto marcado como dirty! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
}
}
}
@Override
public boolean ___isDirty() {
return ___dirty;
}
@Override
public void ___removeDirtyMark() {
this.___dirty = false;
}
@Override
public void ___commit() {
if (this.___dirty) {
....
....
lot's of code here
...
...
// quitar la marca de dirty
this.___dirty = false;
}
}
@Override
public void ___rollback() {
}
}
公共接口IObjectProxy{
公共方向顶点uu_ugetVertex();
公共字符串\uuuuu getRid();
公共空间uuu_uu设置顶点(方向顶点v);
公共方向顶点(getEdge();
公共空间uuuuu setEdge(OrientEdge v);
公共类uuuu getBaseClass();
公共对象\uuuuu getProxiObject();
公共布尔值;
公共无效(已删除的IRTYMARK();
公共无效提交();
public void uuu rollback();
}
公共类ObjectProxyFactory实现MethodInterceptor、IObjectProxy{
私有最终静态记录器Logger=Logger.getLogger(ObjectProxyFactory.class.getName());
//实物
私有对象\代理对象;
私有类\uuuuuuuu基类;
//这是一个很好的选择。
//私有定向顶点基顶点;
私人定向元素uuuu基本元素;
私人会话管理器;
私有布尔值_;脏=false;
//构造函数-提供的参数是
//要创建其代理的对象
私有ObjectProxyFactory(对象对象对象、定向元素e、会话管理器sm){
这是.uuuuu baseClass=obj.getClass();
这是.\uuuuu baseElement=e;
这个.uuuuuuuuuuuuuuSM=sm;
}
//每次都将调用此方法
//当对象代理调用其任何方法时
@凌驾
公共对象拦截(对象o,
方法,,
对象[]args,
MethodProxy(MethodProxy)抛出可丢弃的{
//响应对象
对象res=null;
//以前
//测量当前时间
//长时间1=System.currentTimeMillis();
//System.out.println(“截获:“+method.getName());
//拉马多修正案
开关(方法.getName()){
案例“\uuuuu getVertex”:
res=这个;
打破
案例“\uuuu getRid”:
res=这个;
打破
案例“\uuuuu getProxiObject”:
res=这个;
打破
案例“\uuuuu getBaseClass”:
res=this.\uuuuu getBaseClass();
打破
案例“\uuuuuuiDirty”:
res=这个;
打破
案例“\uuuuuuuuuuu removeDirtyMark”:
这个.uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu;
打破
案例“提交”:
这个.uuuu提交();
打破
违约:
//使用给定的参数调用实际对象上的方法
//res=methodProxy.invoke(realObj,args);
res=methodProxy.invokeSuper(o,args);
//验证目标的差异。
此.commitTobjectChange();
打破
}
//之后
//打印在代理对象上执行方法所用的时间
//System.out.println(“take:”+(System.currentTimeMillis()-time1)+“ms”);
//返回结果
返回res;
}
私有void setProxyObject(对象po){
这是.\uuuxyObject=po;
}
公共静态T createProxy(T obj、OrienteElement ov、SessionManager sm){
//这是cglib api的主要入口点
//此对象将使用新功能“增强”(就CGLIB而言)
//可以将此类视为动态代理的“构建器”
增强子e=新增强子();
//该类将从真实类扩展而来
e、 setSuperclass(obj.getClass());
//我们必须声明拦截器-其“intercept”的类
//将在调用代理对象的任何方法时调用。
ObjectProxyFactory opf=新的ObjectProxyFactory(obj、ov、sm);
e、 setCallback(opf);
e、 setInterfaces(新类[]{IObjectProxy.Class});
//现在增强器已经配置好,我们将创建代理对象
T proxifiedObj=(T)e.create();
opf.setProxyObject(proxifiedObj);
//对象已准备好使用-返回它
返回proxifiedObj;
}
/**
*在不存在的情况下,一个不存在的代理是无效的。
*
*@返回
*/
@凌驾
面向公共的顶点\uuuuu getVertex(){
if(this.\uuuuu baseElement.getElementType().equals(“顶点”)){
返回(OrientVertex)此元素;
}否则{
返回null;
}
}
/**
*在不存在的情况下,一个不存在的代理是无效的。
*
*@返回
*/
@凌驾
公共字符串\uuuuu getRid(){
if(this.\uuuuu baseElement!=null){
返回此值。uuuuu baseElement.getId().toString();
}否则{
返回null;
}
}
/**
*
*科莫联合国基地元素庄园。
*
*@param v
*/
@凌驾
公共无效设置顶点(方向顶点v){
这是.uuuuu baseElement=v;
}
/**
*在不存在的情况下,一个不存在的代理是无效的。
*
*@返回
*/
@凌驾
公共方向顶点(getEdge)(){
if(this.\uuuu baseElement.getElementType().equals(“Edge”)){
返回(OrientVertex)此元素;
}否则{
返回null;
}
}
/**
*
*科莫联合国基地元素庄园。
*
*@param v
*/
@凌驾
公共空间设置边缘(方向边缘e){
这是.\uuuuu baseElement=e;
}
@凌驾
公共对象\uuuuu getProxiObject(){
返回此属性。\uuuuxyObject;
}
@凌驾
公共类
public class ObjectProxy implements IObjectProxy {
private final static Logger LOGGER = Logger.getLogger(ObjectProxy.class.getName());
// the real object
private Object ___proxyObject;
private Class<?> ___baseClass;
// Vértice desde el que se obtiene el objeto.
// private OrientVertex baseVertex;
private OrientElement ___baseElement;
private SessionManager ___sm;
private boolean ___dirty = false;
// constructor - the supplied parameter is an
// object whose proxy we would like to create
public ObjectProxy(Object obj, OrientElement e, SessionManager sm) {
this.___baseClass = obj.getClass();
this.___baseElement = e;
this.___sm = sm;
}
public ObjectProxy(Class c, OrientElement e, SessionManager sm) {
this.___baseClass = c;
this.___baseElement = e;
this.___sm = sm;
}
// this method will be called each time
// when the object proxy calls any of its methods
@RuntimeType
public Object intercept(@SuperCall Callable<?> zuper, @This Object thiz, @Origin Method method) throws Exception {
// response object
Object res = null;
// BEFORE
// measure the current time
// long time1 = System.currentTimeMillis();
// System.out.println("intercepted: " + method.getName());
// modificar el llamado
switch (method.getName()) {
case "___getVertex":
res = this.___getVertex();
break;
case "___getRid":
res = this.___getRid();
break;
case "___getProxiObject":
res = this.___getProxiObject();
break;
case "___getBaseClass":
res = this.___getBaseClass();
break;
case "___isDirty":
res = this.___isDirty();
break;
case "___removeDirtyMark":
this.___removeDirtyMark();
break;
case "___commit":
this.___commit();
break;
default:
// invoke the method on the real object with the given params
res = zuper.call();
// verificar si hay diferencias entre los objetos.
this.commitObjectChange();
break;
}
// AFTER
// print how long it took to execute the method on the proxified object
// System.out.println("Took: " + (System.currentTimeMillis() - time1) + " ms");
// return the result
return res;
}
...
// the same as above
...
}
public class ObjectProxyFactory {
private final static Logger LOGGER = Logger.getLogger(ObjectProxyFactory.class .getName());
/**
* Devuelve un proxy a partir de un objeto existente y copia todos los valores del objeto original al
* nuevo objecto provisto por el proxy
* @param <T>
* @param o
* @param oe
* @param sm
* @return
*/
public static <T> T create(T o, OrientElement oe, SessionManager sm ) {
T po = null;
try {
ObjectProxy bbi = new ObjectProxy(o,oe,sm);
po = (T) new ByteBuddy()
.subclass(o.getClass())
.implement(IObjectProxy.class)
.method(isDeclaredBy(IObjectProxy.class))
.intercept(MethodDelegation.to(bbi))
.make()
.load(o.getClass().getClassLoader(), ClassLoadingStrategy.Default.INJECTION)
.getLoaded().newInstance();
} catch (InstantiationException ex) {
Logger.getLogger(ObjectProxyFactory.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(ObjectProxyFactory.class.getName()).log(Level.SEVERE, null, ex);
}
return po;
}
/**
* Devuelve un proxy a partir de una definición de clase.
* @param <T>
* @param c
* @param ov
* @param sm
* @return
*/
public static <T> T create(Class<T> c, OrientElement ov, SessionManager sm ) {
T po = null;
try {
ObjectProxy bbi = new ObjectProxy(c,ov,sm);
po = (T) new ByteBuddy()
.subclass(c)
.implement(IObjectProxy.class)
.method(isDeclaredBy(IObjectProxy.class))
.intercept(MethodDelegation.to(bbi))
.make()
.load(c.getClass().getClassLoader(), ClassLoadingStrategy.Default.INJECTION)
.getLoaded().newInstance();
} catch (InstantiationException ex) {
Logger.getLogger(ObjectProxyFactory.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(ObjectProxyFactory.class.getName()).log(Level.SEVERE, null, ex);
}
return po;
}
}
.load(getSystemClassLoader(), ClassLoadingStrategy.Default.INJECTION)