从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
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
相关文章推荐
- Hibernate源码解析 Hibernate中的动态代理Javassist
- 获得spring的指定目标对象,执行指定方法(JDK动态代理,cglib动态代理,Dubbo-Javassist代理)
- Hibernate源码解析 Hibernate中的动态代理Javassist
- 注解的力量 -----Spring 2.5 JPA hibernate 使用方法的点滴整理(三):通过 @Autowired的使用来消除 set ,get方法。
- 注解的力量 -----Spring 2.5 JPA hibernate 使用方法的点滴整理(三):通过 @Autowired的使用来消除 set ,get方法。
- spring AOP 动态代理 jkd动态代理和cglib动态代理 hibernate使用cglib延迟加载
- Spring Data Jpa(Hibernate) OneToMany
- 注解的力量 -----Spring 2.5 JPA hibernate 使用方法的点滴整理(三):通过 @Autowired的使用来消除 set ,get方法。
- spring整合hibernate中的动态代理问题
- 通过 @Autowired的使用来消除 set ,get方法 ---- Spring · JPA ·hibernate 的使用方法
- spring-data-jpa中findOne与getOne的区别 getOne没数据 findOne有数据
- 【Java EE 学习 50】【Spring学习第二天】【使用注解的DI实现】【spring中的继承】【动态代理伪hibernate实现】
- springboot jpa hibernate 实现动态查询
- Hibernate源码解析 Hibernate中的动态代理Javassist
- springboot jpa hibernate 实现动态查询
- Spring Data JPA 中findOne() 和 getOne()的区别
- 注解的力量 -----Spring 2.5 JPA hibernate 使用方法的点滴整理(三):通过 @Autowired的使用来消除 set ,get方法。
- springboot jpa hibernate 实现动态查询
- 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。
- spring data jpa hibernate jpa 三者之间的关系