您的位置:首页 > 编程语言 > Java开发

从spring jpa getone 说到 Hibernate中的动态代理Javassist

2017-05-02 21:47 337 查看
上一章写到 时候谈到 personRepository.getOne(id) ,在调用 proxy-> aop ReflectiveMethodInvocation. proceed() 一系列的interceptorOrInterceptionAdvice 后,然后调用 SimpleJpaRepository.getOne(id)--> SessionImpl.load(class,id),现在你只需要知道从这儿开始就可以了。

JavassistProxyFactory#getProxy(Serializable, SessionImplementor),这里的JavassistProxyFactory这类是在Hibernate启动的时候创建的,由EntityPersister
创建的。一个POJO对应有一个EntityPersister,一个EntityPersister对应有一个ProxyFactory(JavassistProxyFactory)。

如何获取代理对象:JavassistProxyFactory在Hibernate启动的时候就创建了,创建之后,EntityPersister还对它进行了初始化(JavassistProxyFactory#postInstance(……);)这部分如下

SessionImpl.load(class,id) 后面的 DefaultLoadEventListener.proxyOrLoad() 选择相关的proxy,其实 每个都类都有自己的一个ProxyFactory(javassist.util.proxy.ProxyFactory)。这个对象用来生产Proxy对象,生产该POJO的代理对象。在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法,JavassistLazyInitializer
执行 JavassistLazyInitializer.invoke(...)

@Override

public Object invoke(

final Object proxy,

final Method thisMethod,

final Method proceed,

final Object[] args) throws Throwable {

if ( this.constructed ) {

// HHH-10922 - Internal calls to bytecode enhanced methods cause proxy to be initialized

if ( thisMethod.getName().startsWith( "$$_hibernate_" ) ) {

return proceed.invoke( proxy, args );

}

Object result;

try {

result = this.invoke( thisMethod, args, proxy );

}

catch ( Throwable t ) {

throw new Exception( t.getCause() );

}

if ( result == INVOKE_IMPLEMENTATION ) {

Object target = getImplementation();

final Object returnValue;

try {

if ( ReflectHelper.isPublic( persistentClass, thisMethod ) ) {

if ( !thisMethod.getDeclaringClass().isInstance( target ) ) {

throw new ClassCastException(

target.getClass().getName()

+ " incompatible with "

+ thisMethod.getDeclaringClass().getName()

);

}

returnValue = thisMethod.invoke( target, args );

}

else {

thisMethod.setAccessible( true );

returnValue = thisMethod.invoke( target, args );

}

if ( returnValue == target ) {

if ( returnValue.getClass().isInstance( proxy ) ) {

return proxy;

}

else {

LOG.narrowingProxy( returnValue.getClass() );

}

}

return returnValue;

}

catch ( InvocationTargetException ite ) {

throw ite.getTargetException();

}

}

else {

return result;

}

}

else {

// while constructor is running

if ( thisMethod.getName().equals( "getHibernateLazyInitializer" ) ) {

return this;

}

else {

return proceed.invoke( proxy, args );

}

}

}

为什么这样干,都是为了延迟加载对象,所以

但是,这个是回对象不是需要的,需要自动过滤掉 hibernateLazyInitializer 属性。一般在返回给前端领域对象vo 之前,需要对象未必完全符合,一般都需要组装一次加工,完成目标需要数据格式。

看看,仅仅需要一个对象,就完成 多次 aop 代理,在aop interceptor 链式中,然后后面也是层层proxy,至少四层proxy,性能消耗肯定是有的。

参考文章:
http://blog.csdn.net/zteny/article/details/13991523
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐