设为首页 收藏本站
查看: 1022|回复: 0

[经验分享] 加速Java应用开发速度1——加速spring/hibernate应用调试时启动速度

[复制链接]

尚未签到

发表于 2017-3-1 09:29:40 | 显示全部楼层 |阅读模式
  在调试spring应用时,动辄几十秒,甚至有的应用上分钟的启动速度,会让整个调试速度慢下来了。等待时间让人抓狂。不知道大家是如何加速spring应用调试速度的,在此分享下我的一次加速过程。欢迎补充指正。
环境
  配置:
  thinkpad t410
  内存:4G内存
  CPU:Intel P8700 双核2.53GHZ
  系统:WIN XP
  开发工具:Intellij IDEA 12.0.4
  Maven + spring3.2.3 + hibernate4.2.2+Spring data jpa 1.3.1
  未优化前spring容器启动速度:
  16890毫秒 =(14609毫秒(ContextLoaderListener加载的)+2281毫秒(Springmvc加载的)
  优化后spring容器启动速度:
  7797毫秒 =(6563毫秒(ContextLoaderListener加载的)+1234毫秒(Springmvc加载的)
  速度提升了一半多,而且以后在调试阶段,大部分就停留在这个时间左右。
  注意:此处只是spring容器启动速度,不包括服务器启动时的速度。因为我的系统好久没清理了,否则可能速度会更快。
加速Spring
  1、扫描注解Bean
  写比较精确的扫描路径,如扫描@Service和@Repository:



Xml代码   DSC0000.png

  • <context:component-scan base-package="com.sishuok.es.**.repository,com.sishuok.es.**.service,com.sishuok.es.**.extra">  
  这样写,比直接写com.sishuok.es速度要快很多,因为这样扫描的class会很少。
  还有,如springmvc 扫描:



Xml代码  

  • <context:component-scan base-package="com.sishuok.es.**.web.controller" use-default-filters="false">  
  此处只扫描项目的web.controller包,这样扫描的class也很少。
  还有如事务的扫描:



Xml代码  

  • execution(* com.sishuok.es..service..*+.*(..)
  还有如使用spring data jpa时也是这样:



Xml代码  

  • <jpa:repositories  
  •             base-package="com.sishuok.es.**.repository"  
  这里需要大家有良好的分包,否则无法优化。
  2、延迟加载你的bean
  常见的方式是在配置文件中在<beans>上加:



Xml代码  

  • default-lazy-init="true"  
  2.1、这种方式可能对如任务调度等没有依赖的情况造成影响;
  2.2、在正式机环境还是非lazy bean的好,这样可以在启动时发现一些可能存在的问题;
  2.2、还有就是如果你使用springmvc,lazy-init几乎没啥用,因为springmvc容器在启动时会通过DefaultAnnotationHandlerMapping查找相关的带有@RequestMapping的bean并注册请求映射;所以相关的如Service/Repository也级联非lazy-init;
  因此我写了个工具:SpeedUpSpringProcessor,其作用是:在调试时lazy-init所有bean;具体配置请参考最后。
  3、移除调试阶段不相干的bean
  有些bean在调试阶段我们并不需要,如我们在测试用户模块时,可能不需要测试权限模块;此时我们可以把不相干的bean移除掉;具体配置请参考最后。
  这样的话,可以考虑如把@Controller的bean移除,这样的话如Service/Repository就可以lazy-init了。
  常见的可以移除的如:
  任务调度器(quartz)、AOP相关等等;
  此处需要合理的分包,否则无法应用或应用困难。
  4、删除无用属性
  如在测试shiro时,可能不需要remember的功能,此时可以把属性移除/禁用(即将值设置为false);具体配置请参考最后。
  5、替换正式机数据源为最快的数据源
  如此处我把DruidDataSource数据源直接替换为org.springframework.jdbc.datasource.DriverManagerDataSource,这个速度最快;
  6、替换jackson为fastjson
  此处测试了下jackson速度比fastjson慢许多的。支持国产。
  7、项目分模块开发
  如果项目模块比较多,可以考虑放弃注解,而使用xml配置方式+约定。
  因为实际做项目时可能把配置分到多个配置文件,此时我尝试了下合并到一个,几乎没啥速度提升,所以还是分开存好。
  到此spring容器启动速度算是比较快了,不知道大家还有没有好的策略。欢迎指点。
加速Hibernate/JPA
  此处以org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean为例。
  1、 精确化packagesToScan
  和之前的spring一样,写比较精确的实体扫描路径



Xml代码  

  • <property name="packagesToScan" value="com.sishuok.es.**.entity"/>  
  2、generateDdl=false 禁用掉
  没必要每次都生成ddl
  3、 禁用JSR-303验证
  默认情况下是AUTO,会根据classpath下是否有jsr-303实现来自动注册;



Xml代码  

  • <!-- 使用自定义的validator进行jsr303验证 -->  
  • <entry key="javax.persistence.validation.factory" value-ref="validator"/>  
  • <!-- jsr303验证模式 因为其要么验证 要么不验证 不能按照规则走 所以此处禁用 -->  
  • <!-- #http://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html/configuration.html -->  
  • <entry key="javax.persistence.validation.mode" value="NONE"/>  
  此处validator 直接引用我们项目中定义的,而不是让hibernate再去new一个。而且也不推荐在这验证,具体为什么,请参考我的《我是这样认识注解和XML的》。
  4、如果你的项目都是注解,此时就没必要扫描hbm了,禁用掉



Xml代码  

  • <entry key="hibernate.archive.autodetection" value="class"/>  
  5、如果你不使用NamedQuery,禁用掉



Xml代码  

  • <entry key="hibernate.query.startup_check" value="false"/>  
  6、在调试阶段禁用掉二级缓存
  通过如上手段,我的spring容器启动速度提升了一半多。大家还有好的优化策略吗?如果有欢迎补充。具体配置请参考最后。
  之前提到的SpeedUpSpringProcessor配置



Xml代码  

  • <!-- 优化spring启动 通过移除bean定义 和 lazy init 实现 -->  
  • <bean class="com.sishuok.es.common.spring.SpeedUpSpringProcessor">  
  •     <!-- 需要从bean定义中移除的bean的名字 -->  
  •     <property name="removedBeanNames">  
  •         <list>  
  •             <!-- spring-config-quartz.xml -->  
  •             <value>scheduler</value>  
  •             <value>autoClearDeletedRelationTrigger</value>  
  •             <value>autoClearExpiredOrDeletedmMessageTrigger</value>  
  •             <value>autoClearDeletedRelationJob</value>  
  •             <value>autoClearExpiredOrDeletedmMessageJob</value>  

  •             <!-- spring-config-shiro.xml -->  
  •             <value>rememberMeCookie</value>  
  •             <value>rememberMeManager</value>  
  •             <value>shiroCacheManager</value>  
  •             <value>sessionValidationScheduler</value>  
  •             <value>sessionValidationScheduler</value>  
  •             <!-- spring-mvc.xml -->  
  •             <value>multipartResolver</value>  

  •             <!-- spring-config-monitor.xml -->  
  •             <value>druidStatInterceptor</value>  
  •             <value>druidAdvisor</value>  
  •         </list>  
  •     </property>  
  •     <!-- 需要从bean定义中移除的bean的属性 -->  
  •     <!--替换掉的属性值 see removedBeanProperties 只支持简单属性-->  
  •     <property name="removeOrReplaceBeanProperties">  
  •         <list>  
  •             <!-- spring-config-shiro.xml -->  
  •             <value>sessionManager#cacheManager</value>  
  •             <value>sessionManager#cacheManager</value>  
  •             <value>sessionManager#sessionValidationScheduler</value>  
  •             <value>securityManager#rememberMeManager</value>  

  •             <!-- spring-config.xml -->  
  •             <value>entityManagerFactory#jpaPropertyMap#hibernate.default_batch_fetch_size"</value>  
  •             <value>entityManagerFactory#jpaPropertyMap#hibernate.max_fetch_depth"</value>  
  •             <value>entityManagerFactory#jpaPropertyMap#hibernate.generate_statistics</value>  
  •             <value>entityManagerFactory#jpaPropertyMap#hibernate.bytecode.use_reflection_optimizer</value>  
  •             <value>entityManagerFactory#jpaPropertyMap#hibernate.cache.use_second_level_cache=false</value>  
  •             <value>entityManagerFactory#jpaPropertyMap#hibernate.cache.use_query_cache</value>  
  •             <value>entityManagerFactory#jpaPropertyMap#hibernate.cache.region.factory_class</value>  
  •             <value>entityManagerFactory#jpaPropertyMap#hibernate.cache.use_structured_entries</value>  
  •             <value>entityManagerFactory#jpaPropertyMap#net.sf.ehcache.configurationResourceName</value>  
  •         </list>  
  •     </property>  

  •     <!-- 需要从bean定义中移除指定的类类型 正则表达式-->  
  •     <property name="removedClassPatterns">  
  •         <list>  
  •              <value>com\.sishuok\.es\.showcase.*</value>  
  •              <value>com\.sishuok\.es\.monitor.*</value>  
  •              <value>com\.sishuok\.es\.extra\.aop.*</value>  
  •              <value>com\.sishuok\.es\.extra\.quartz.*</value>  
  •              <value>com\.sishuok\.es\.conf.*</value>  
  •              <!--<value>com\.sishuok\.es\.personal.*\.web\.controller.*</value>-->  
  •              <!--<value>com\.sishuok\.es\.sys.*\.web\.controller.*</value>-->  
  •         </list>  
  •     </property>  

  •     <!-- 指定非延迟加载的bean-->  
  •     <property name="noneLazyBeanNames">  
  •         <list>  
  •             <value>domainClassConverter</value>  
  •         </list>  
  •     </property>  
  • </bean>  
  1、默认所有bean lazy-init;
  2、removedClassPatterns:正则表达式,即可以移除的bean的class路径模式,bean class匹配该模式的将移除;此处需要良好的分包,否则不好应用;
  3、removedBeanNames:即在调试期间可以移除的bean;
  4、removeOrReplaceBeanProperties:调试期间可以删除/替换掉的bean属性;
  如移除shiro的sessionManager的cacheManager;
  如禁用hibernate二级缓存:entityManagerFactory#jpaPropertyMap#hibernate.cache.use_second_level_cache=false
  5、noneLazyBeanNames:有些bean不能lazy-init;排除掉。
  具体实现请参考:
  可以直接下载使用。
  SpeedUpSpringProcessor:
  https://github.com/zhangkaitao/es/blob/master/common/src/main/java/com/sishuok/es/common/spring/SpeedUpSpringProcessor.java
  spring-speed-up.xml:
  https://github.com/zhangkaitao/es/blob/master/web/src/main/resources/spring-speed-up.xml
  其他提到的配置文件都在:
  https://github.com/zhangkaitao/es/tree/master/web/src/main/resources
  开启/关闭:
  此处我使用了spring的profile:



Java代码  

  • <beans profile="development" >  
  即只有当System.getProperties中有spring.profiles.active=developement才执行调试模式,所以如果没有该配置还是走的正常流程,对系统没有影响,所以此处大家可以使用:
  1、jetty内嵌执行时设置该属性



Xml代码  

  • <plugin>  
  •     <groupId>org.mortbay.jetty</groupId>  
  •     <artifactId>jetty-maven-plugin</artifactId>  
  •     <version>${jetty.version}</version>  
  •     <configuration>  
  •         ---省略
  •         <!-- spring profile  -->  
  •         <systemProperties>  
  •             <systemProperty>  
  •                 <name>spring.profiles.active</name>  
  •                 <value>development</value>  
  •             </systemProperty>  
  •         </systemProperties>  
  •     </configuration>  
  • </plugin>  
  2、写多个bat文件分别执行不同的情况。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-348621-1-1.html 上篇帖子: 百度BAE JAVA环境项目部署和调试 下篇帖子: moco-简述
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表