休眠字节码增强

介绍

既然您了解了Hibernate脏检查的基础知识 ,我们就可以研究增强的脏检查机制。 虽然默认的图遍历算法对于大多数用例可能已足够,但有时您需要优化的脏检查算法,并且检测方法比构建自己的自定义策略更方便。

使用Ant休眠工具

传统上,Hibernate Tools一直专注于Ant和Eclipse。 从Hibernate 3开始就可以进行字节码检测,但是它需要Ant任务才能运行CGLIB或Javassist字节码增强例程。

Maven支持通过maven-antrun-plugin运行Ant任务:

<build><plugins><plugin><artifactId>maven-antrun-plugin</artifactId><executions><execution><id>Instrument domain classes</id><configuration><tasks><taskdef name="instrument"classname="org.hibernate.tool.instrument.javassist.InstrumentTask"><classpath><path refid="maven.dependency.classpath"/><path refid="maven.plugin.classpath"/></classpath></taskdef><instrument verbose="true"><fileset dir="${project.build.outputDirectory}"><include name="**/flushing/*.class"/></fileset></instrument></tasks></configuration><phase>process-classes</phase><goals><goal>run</goal></goals></execution></executions><dependencies><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-core</artifactId><version>${hibernate.version}</version></dependency><dependency><groupId>org.javassist</groupId><artifactId>javassist</artifactId><version>${javassist.version}</version></dependency></dependencies></plugin></plugins>
</build>

因此,对于以下实体源类:

@Entity
public class EnhancedOrderLine {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;private Long number;private String orderedBy;private Date orderedOn;public Long getId() {return id;}public Long getNumber() {return number;}public void setNumber(Long number) {this.number = number;}public String getOrderedBy() {return orderedBy;}public void setOrderedBy(String orderedBy) {this.orderedBy = orderedBy;}public Date getOrderedOn() {return orderedOn;}public void setOrderedOn(Date orderedOn) {this.orderedOn = orderedOn;}
}

在构建期间,将生成以下类:

@Entity
public class EnhancedOrderLine implements FieldHandled {@Id@GeneratedValue(strategy=GenerationType.AUTO)private Long id;private Long number;private String orderedBy;private Date orderedOn;private transient FieldHandler $JAVASSIST_READ_WRITE_HANDLER;public Long getId() {return $javassist_read_id();}public Long getNumber() {return $javassist_read_number();}public void setNumber(Long number) {$javassist_write_number(number);}public String getOrderedBy() {return $javassist_read_orderedBy();}public void setOrderedBy(String orderedBy) {$javassist_write_orderedBy(orderedBy);}public Date getOrderedOn() {return $javassist_read_orderedOn();}public void setOrderedOn(Date orderedOn) {$javassist_write_orderedOn(orderedOn);}public FieldHandler getFieldHandler() {return this.$JAVASSIST_READ_WRITE_HANDLER;}public void setFieldHandler(FieldHandler paramFieldHandler) {this.$JAVASSIST_READ_WRITE_HANDLER = paramFieldHandler;}public Long $javassist_read_id() {if (getFieldHandler() == null)return this.id;}public void $javassist_write_id(Long paramLong) {if (getFieldHandler() == null) {this.id = paramLong;return;}this.id = ((Long)getFieldHandler().writeObject(this, "id", this.id, paramLong));}public Long $javassist_read_number() {if (getFieldHandler() == null)return this.number;}public void $javassist_write_number(Long paramLong) {if (getFieldHandler() == null) {this.number = paramLong;return;}this.number = ((Long)getFieldHandler().writeObject(this, "number", this.number, paramLong));}public String $javassist_read_orderedBy() {if (getFieldHandler() == null)return this.orderedBy;}public void $javassist_write_orderedBy(String paramString) {if (getFieldHandler() == null) {this.orderedBy = paramString;return;}this.orderedBy = ((String)getFieldHandler().writeObject(this, "orderedBy", this.orderedBy, paramString));}public Date $javassist_read_orderedOn() {if (getFieldHandler() == null)return this.orderedOn;}public void $javassist_write_orderedOn(Date paramDate) {if (getFieldHandler() == null) {this.orderedOn = paramDate;return;}this.orderedOn = ((Date)getFieldHandler().writeObject(this, "orderedOn", this.orderedOn, paramDate));}
}

尽管org.hibernate.bytecode.instrumentation.spi.AbstractFieldInterceptor设法拦截脏字段,但在进行脏污跟踪时从未真正询问过此信息。

InstrumentTask字节码增强功能只能分辨一个实体是否脏了,缺乏对指示已修改哪些属性的支持,因此使InstrumentTask更适合“ No-proxy” LAZY提取策略 。

休眠增强Maven插件

Hibernate 4.2.8增加了对专用Maven字节码增强插件的支持 。

Maven字节码增强插件易于配置:

<build><plugins><plugin><groupId>org.hibernate.orm.tooling</groupId><artifactId>hibernate-enhance-maven-plugin</artifactId><executions><execution><phase>compile</phase><goals><goal>enhance</goal></goals></execution></executions></plugin></plugins>
</build>

在项目构建期间,将生成以下类:

@Entity
public class EnhancedOrderLineimplements ManagedEntity, PersistentAttributeInterceptable, SelfDirtinessTracker {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;private Long number;private String orderedBy;private Date orderedOn;@Transientprivate transient PersistentAttributeInterceptor $$_hibernate_attributeInterceptor;@Transientprivate transient Set $$_hibernate_tracker;@Transientprivate transient CollectionTracker $$_hibernate_collectionTracker;@Transientprivate transient EntityEntry $$_hibernate_entityEntryHolder;@Transientprivate transient ManagedEntity $$_hibernate_previousManagedEntity;@Transientprivate transient ManagedEntity $$_hibernate_nextManagedEntity;public Long getId() {return $$_hibernate_read_id();}public Long getNumber() {return $$_hibernate_read_number();}public void setNumber(Long number) {$$_hibernate_write_number(number);}public String getOrderedBy() {return $$_hibernate_read_orderedBy();}public void setOrderedBy(String orderedBy) {$$_hibernate_write_orderedBy(orderedBy);}public Date getOrderedOn() {return $$_hibernate_read_orderedOn();}public void setOrderedOn(Date orderedOn) {$$_hibernate_write_orderedOn(orderedOn);}public PersistentAttributeInterceptor $$_hibernate_getInterceptor() {return this.$$_hibernate_attributeInterceptor;}public void $$_hibernate_setInterceptor(PersistentAttributeInterceptor paramPersistentAttributeInterceptor) {this.$$_hibernate_attributeInterceptor = paramPersistentAttributeInterceptor;}public void $$_hibernate_trackChange(String paramString) {if (this.$$_hibernate_tracker == null)this.$$_hibernate_tracker = new HashSet();if (!this.$$_hibernate_tracker.contains(paramString))this.$$_hibernate_tracker.add(paramString);}private boolean $$_hibernate_areCollectionFieldsDirty() {return ($$_hibernate_getInterceptor() != null) && (this.$$_hibernate_collectionTracker != null);}private void $$_hibernate_getCollectionFieldDirtyNames(Set paramSet) {if (this.$$_hibernate_collectionTracker == null)return;}public boolean $$_hibernate_hasDirtyAttributes() {return ((this.$$_hibernate_tracker == null) || (this.$$_hibernate_tracker.isEmpty())) && ($$_hibernate_areCollectionFieldsDirty());}private void $$_hibernate_clearDirtyCollectionNames() {if (this.$$_hibernate_collectionTracker == null)this.$$_hibernate_collectionTracker = new CollectionTracker();}public void $$_hibernate_clearDirtyAttributes() {if (this.$$_hibernate_tracker != null)this.$$_hibernate_tracker.clear();$$_hibernate_clearDirtyCollectionNames();}public Set<String> $$_hibernate_getDirtyAttributes() {if (this.$$_hibernate_tracker == null)this.$$_hibernate_tracker = new HashSet();$$_hibernate_getCollectionFieldDirtyNames(this.$$_hibernate_tracker);return this.$$_hibernate_tracker;}private Long $$_hibernate_read_id() {if ($$_hibernate_getInterceptor() != null)this.id = ((Long) $$_hibernate_getInterceptor().readObject(this, "id", this.id));return this.id;}private void $$_hibernate_write_id(Long paramLong) {if (($$_hibernate_getInterceptor() == null) || ((this.id == null) || (this.id.equals(paramLong))))break label39;$$_hibernate_trackChange("id");label39:Long localLong = paramLong;if ($$_hibernate_getInterceptor() != null)localLong = (Long) $$_hibernate_getInterceptor().writeObject(this, "id", this.id, paramLong);this.id = localLong;}private Long $$_hibernate_read_number() {if ($$_hibernate_getInterceptor() != null)this.number = ((Long) $$_hibernate_getInterceptor().readObject(this, "number", this.number));return this.number;}private void $$_hibernate_write_number(Long paramLong) {if (($$_hibernate_getInterceptor() == null) || ((this.number == null) || (this.number.equals(paramLong))))break label39;$$_hibernate_trackChange("number");label39:Long localLong = paramLong;if ($$_hibernate_getInterceptor() != null)localLong = (Long) $$_hibernate_getInterceptor().writeObject(this, "number", this.number, paramLong);this.number = localLong;}private String $$_hibernate_read_orderedBy() {if ($$_hibernate_getInterceptor() != null)this.orderedBy = ((String) $$_hibernate_getInterceptor().readObject(this, "orderedBy", this.orderedBy));return this.orderedBy;}private void $$_hibernate_write_orderedBy(String paramString) {if (($$_hibernate_getInterceptor() == null) || ((this.orderedBy == null) || (this.orderedBy.equals(paramString))))break label39;$$_hibernate_trackChange("orderedBy");label39:String str = paramString;if ($$_hibernate_getInterceptor() != null)str = (String) $$_hibernate_getInterceptor().writeObject(this, "orderedBy", this.orderedBy, paramString);this.orderedBy = str;}private Date $$_hibernate_read_orderedOn() {if ($$_hibernate_getInterceptor() != null)this.orderedOn = ((Date) $$_hibernate_getInterceptor().readObject(this, "orderedOn", this.orderedOn));return this.orderedOn;}private void $$_hibernate_write_orderedOn(Date paramDate) {if (($$_hibernate_getInterceptor() == null) || ((this.orderedOn == null) || (this.orderedOn.equals(paramDate))))break label39;$$_hibernate_trackChange("orderedOn");label39:Date localDate = paramDate;if ($$_hibernate_getInterceptor() != null)localDate = (Date) $$_hibernate_getInterceptor().writeObject(this, "orderedOn", this.orderedOn, paramDate);this.orderedOn = localDate;}public Object $$_hibernate_getEntityInstance() {return this;}public EntityEntry $$_hibernate_getEntityEntry() {return this.$$_hibernate_entityEntryHolder;}public void $$_hibernate_setEntityEntry(EntityEntry paramEntityEntry) {this.$$_hibernate_entityEntryHolder = paramEntityEntry;}public ManagedEntity $$_hibernate_getPreviousManagedEntity() {return this.$$_hibernate_previousManagedEntity;}public void $$_hibernate_setPreviousManagedEntity(ManagedEntity paramManagedEntity) {this.$$_hibernate_previousManagedEntity = paramManagedEntity;}public ManagedEntity $$_hibernate_getNextManagedEntity() {return this.$$_hibernate_nextManagedEntity;}public void $$_hibernate_setNextManagedEntity(ManagedEntity paramManagedEntity) {this.$$_hibernate_nextManagedEntity = paramManagedEntity;}
}

很容易意识到,新的字节码增强逻辑与以前的InstrumentTask生成的逻辑不同。

与自定义脏检查机制类似,新的字节码增强版本记录了已更改的属性,而不仅仅是一个简单的脏布尔标志。 更改时,增强逻辑会标记脏字段。 这种方法比必须将所有当前属性值与加载时快照数据进行比较要有效得多。

我们到了吗?

即使实体类字节码得到了增强,使用Hibernate 4.3.6 仍然以某种方式缺少一些拼图 。

例如,当调用setNumber(Long number)时 ,将执行以下拦截方法:

private void $$_hibernate_write_number(Long paramLong) {if (($$_hibernate_getInterceptor() == null) || ((this.number == null) || (this.number.equals(paramLong))))break label39;$$_hibernate_trackChange("number");label39:Long localLong = paramLong;if ($$_hibernate_getInterceptor() != null)localLong = (Long) $$_hibernate_getInterceptor().writeObject(this, "number", this.number, paramLong);this.number = localLong;}

在我的示例中,$$ _ hibernate_getInterceptor()始终为null,从而绕过$$ _ hibernate_trackChange(“ number”)调用。 因此,将不会记录任何脏属性,从而迫使Hibernate退回到默认的深度比较脏检查算法 。

因此,即使Hibernate在该特定领域取得了长足的进步,肮脏检查的增强仍然需要额外的工作才能变得容易获得。

  • 代码可在GitHub上获得 。

翻译自: https://www.javacodegeeks.com/2014/09/hibernate-bytecode-enhancement.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/362272.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hibernate核心接口

一、Configuration类&#xff1a;1、 作用&#xff1a;&#xff08;1&#xff09;管理hibernate配置信息&#xff08;2&#xff09;读取hibernate.cfg.xml文件&#xff08;3&#xff09;加载hibernate的驱动&#xff0c;例如&#xff1a;url,用户名&#xff08;4&#xff09;管…

CSS实现垂直居中的方法

CSS实现垂直居中的方法 1、relative absolute定位&#xff1a; (1)css html代码 1 <!doctype html>2 <html lang"en">3 4 <head>5 <meta charset"UTF-8" />6 <title>Document</title>7 …

Neo4j:收集多个值

在Neo4j的密码查询语言中&#xff0c;我最喜欢的功能之一是COLLECT&#xff0c;它使我们能够将项目分组到一个数组中以备后用。 但是&#xff0c;我注意到人们有时很难弄清楚如何使用COLLECT收集多个项目&#xff0c;并且很难找到一种方法。 考虑以下数据集&#xff1a; cre…

spring 概念理解(资料)

一、Spring的IoC(Inversion of Control)。这是Spring中得有特点的一部份。IoC又被翻译成“控制反转”&#xff0c;也不知道是谁翻译得这么别扭&#xff0c;感觉很深奥的词。其实&#xff0c;原理很简单&#xff0c;用一句通俗的话来说&#xff1a;就是用XML来定义生成的对象。I…

运用flask、flask-restful开发rest风格的接口,并使用蓝图增加代码的延展性和可扩展性。...

本人做为一个测试人员&#xff0c;之前也有写过&#xff0c;想要测试好接口&#xff0c;那必须要知道如何开发一个接口的重要性。 之前也写过通flask或者flask-retful开发接口&#xff0c;但那些只是一些最简单的demo&#xff0c;不具有很好延展性和扩展性。 此次我们带一整个完…

2014年夏末大Java新闻

正如即将到来的JavaOne那样 &#xff0c;最近在Java社区中已经有很多重大新闻。 这篇文章简要地引用了其中的三个项目&#xff08;Java SE 8更新&#xff0c;Java SE 9和Java EE 8&#xff09;&#xff0c;并对我发现这是我在类路径/类加载器问题上见过的更清楚的文章之一进行了…

初学 Ajax(涉及 php)

一直知道 ajax 但是尚未真正了解&#xff0c; 这次看了慕课网的《Ajax全接触》&#xff0c;算是有所收获&#xff0c;入了个门。需要用到php&#xff0c;因为 Ajax也是向服务器请求&#xff08;不知道这么解释对不对&#xff09;&#xff0c; 所以还需要配置环境&#xff0c; …

php分页显示

<?php /*** Page Class* 实现各种分页样式* author yangsh*/ class Pager {/*** 数据总数* var integer*/private $totalItems;/*** 每页显示数* var integer*/private $pageSize 20;/*** 页面显示的页码标号的数量* var integer*/private $codeNum 10;/*** 跳转链接* va…

DI容器是代码污染者

尽管依赖项注入 &#xff08;也称为“ DI”&#xff09;是一种在OOP中组成对象的自然技术&#xff08;在Martin Fowler引入该术语之前就已知道&#xff09;&#xff0c;但Spring IoC &#xff0c; Google Guice &#xff0c; Java EE6 CDI &#xff0c; Dagger和其他DI框架将其…

java程序-类的高级特性

创建Employee类&#xff0c;在类中定义三个属性&#xff1a;编号&#xff0c;姓名&#xff0c;年龄&#xff0c;然后在构造方法里初始化这三个属性&#xff0c;最后在实现接口中的定义的CompareTo方法&#xff0c;将对象按编号升序排列。 代码如下&#xff1a;(程序可能有些错误…

js 数组去重

数组去重的思路&#xff0c;突然感觉挺有趣的&#xff0c;来整理一下 两个 for 循环比较的&#xff0c;如下function removeRepeat(arr){ for( var i 0; i < arr.length; i ){ for ( var j i 1; j < arr.length; i ){ if ( a…

CSS中实现水平/垂直居中

CSS中实现水平/垂直居中 在CSS中实现水平居中相对简单&#xff0c;但是却没有一个明确的属性表示这是实现垂直居中的&#xff0c;这就导致垂直居中的实现相对初学者来说难上许多。但是在实际的开发中垂直居中的需求常常出现&#xff0c;例如一行中有左右两部分&#xff0c;左边…

SWF 文件不能访问本地资源 只有仅限于文件系统的 SWF 文件和可信的本地 SWF 文件可以访问本地资源。...

错误信息&#xff1a;SecurityError: Error #2148: SWF 文件 D:/demo/test/index.swf 不能访问本地资源 D:/demo/test/bin-debug/textLayout_4.0.0.10485.swf。只有仅限于文件系统的 SWF 文件和可信的本地 SWF 文件可以访问本地资源。 at flash.net::URLStream/load() at fla…

高并发系统之大忌-慢查询

最近又遇到了一次慢查把db&#xff08;mariadb10)几乎打挂的案例&#xff0c;作为一个核心支付系统的技术负责人&#xff0c;真是每日如履薄冰。因为之前支付系统经常出问题&#xff0c;现在各个BG对支付系统都盯得很紧。这次要不是我及时让DB给暴力清理数据&#xff0c;没准又…

CSS媒体查询

格式&#xff08;style&#xff1a;{}&#xff09;元素设置&#xff1a; body{background-color:#0033FF;}/*媒体查询:当页面宽度最大为960px时*/media screen and (max-width: 960px){/*body背景颜色为*/body{background-color:#FF6699}}media screen and (max-width: 768px){…

(单元测试)JavaBeans的技巧

如果您正在编写Java代码&#xff0c;那么您至少要编写一些遵循JavaBean约定的类&#xff0c;即&#xff0c;具有带有公共getter和setter方法的私有属性的类&#xff0c;包含无参数的构造函数&#xff0c;可序列化&#xff0c;并且遵守Equals和HashCode合同。 最重要的是&#x…

js中的正则表达式

正则表达式等名称并不能让人一下就能明白是什么意思&#xff0c;我认为称之为 规则表达式 更为合理&#xff0c;就是描述一个字符串规则的表达式。 语法 正则表达式的语法有两种&#xff0c;下面第一种语法稍显 怪异&#xff0c;但确实是合法的并且相对方便&#xff0c;推荐。…

Hadoop namenode启动瓶颈分析

转载&#xff1a;http://blog.csdn.net/AE86_FC/archive/2010/08/26/5842020.aspx NameNode启动过程详细剖析 NameNode中几个关键的数据结构 FSImage Namenode会将HDFS的文件和目录元数据存储在一个叫fsimage的二进制文件中&#xff0c;每次保存fsimage之后到下次保存之间的所有…

Java 9 –终极功能列表

这篇文章将针对即将到来的Java 9版本进行更新&#xff0c;新增功能 &#xff08; 最新更新&#xff1a;2014年 9月9日 &#xff09; OpenJDK开发正在加快速度&#xff1a;2014年3月Java 8发布之后&#xff0c;我们预计将进入2年的发布周期。 据报道&#xff0c;Java 9将于2016…

2018.3.30 边框应用与导航栏设置

<!DOCTYPE html><html> <head> <meta charset"utf-8" /> <title></title> <style type"text/css"> /*制作三角形*/ #one{ width: 0px; …