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

       上一章写到 时候谈到   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

你可能感兴趣的:(开发过程遇到bug及解决)