1.JDK编译时注解处理器结合Javapoet动态生成模板化Java源文件
2.å¦ä½å¨XMLä¸ä½¿ç¨èªå®ä¹Animationå¨ç»ç±»
JDK编译时注解处理器结合Javapoet动态生成模板化Java源文件
面对繁复的动画动画业务代码和重复劳动,我们一直在寻求更高效的源码源代解决方案。Lombok的实现出现,通过其注解如@Data,简单定制指标源码查询能自动生成getter、效果setter等方法,动画动画简化了代码编写。源码源代然而,实现对于自定义对象和集合类型,简单如JPA中需要扩展AttributeConverter的效果情况,如何减少手动编写转换类的动画动画flask源码解读繁琐呢?
答案在于利用Java的编译时注解处理器(Annotation Processing Tool,APT)和JavaPoet源代码生成器。源码源代APT在编译阶段处理注解,实现通过动态生成.java源代码,简单能解决重复代码问题。效果JavaPoet则提供了优雅地生成代码的hadoop 1.0源码功能,让代码生成变得轻松。
具体步骤如下:首先,理解AttributeConverter的工作原理,它在Entity和数据库之间建立数据关联。我们创建一个通用的easyui messager 源码Converter基类,如AbstractJsonConverter,用于处理类型转换。接着,定义一个自定义注解JsonAutoConverter,标记需要生成Converter的mapwingis示例源码类,由AnnotationProcessor扫描并处理,生成相应的源代码,如OrderNoticeEventConverter。
通过执行编译命令,我们能在生成的源文件中看到JavaPoet生成的Converter类,它继承自AbstractJsonConverter,实现了特定类型的转换。这个例子展示了如何利用JDK编译时注解处理器结合Javapoet动态生成模板化的Java源文件,以减少重复工作,提升编码效率。
开发中的"小技巧"往往隐藏在深处,只要我们愿意探索,就能发现并应用它们,打开新的编程世界。源码地址:/zhucan/extension-spring-boot-starter/tree/master/jpa-conversion,欢迎有兴趣的朋友查看和学习。
å¦ä½å¨XMLä¸ä½¿ç¨èªå®ä¹Animationå¨ç»ç±»
å¨å®ååºç¨çå¨ç»å¼åä¸ï¼å¯è½SDKä¸èªå¸¦çè¡¥é´å¨ç»ä¸è½æ»¡è¶³åºç¨çéæ±ï¼éè¦å¨Java代ç ä¸èªå®ä¹ä¸äºå¨ç»ç±»ï¼å½ç¶é½æ¯ç»§æ¿èªAnimationç±»ãå®ç°ä¹åï¼æ们ä¸è¬ç´æ¥å¨ä»£ç ä¸ä½¿ç¨ï¼ç±»ä¼¼ä¸é¢è¿æ ·ï¼CustomAnimationcustomAnimation=newCustomAnimation();customAnimation.setDuration();customAnimation.setFillAfter(true);effectView.startAnimation(customAnimation);å½Viewåæ¶è¦åºç¨åScaleï¼Alphaè¿æ ·çè¡¥é´å¨ç»æ¶ï¼ä½ å°±éè¦å¤æ·»å 类似ä¸é¢ç代ç ï¼CustomAnimationcustomAnimation=newCustomAnimation();customAnimation.setDuration();customAnimation.setFillAfter(true);AnimationscaleAnimation=newScaleAnimation(0f,1f,0f,1f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);AnimationalphaAnimation=newAlphaAnimation(0.1f,1.0f);scaleAnimation.setDuration();alphaAnimation.setDuration();AnimationSetset=newAnimationSet(true);set.addAnimation(customAnimation);set.addAnimation(scaleAnimation);set.addAnimation(alphaAnimation);set.setFillAfter(true);set.setFillEnabled(true);effectView.startAnimation(set);å¦æç´æ¥å¨xmlä¸ææéçææè¡¥é´å¨ç»ï¼å æ¬èªå®ä¹å¨ç»ç±»æ¾å°ä¸ä¸ªéåï¼äºæ çèµ·æ¥å°±æ²¡é£ä¹å¤æãå¨xmlå®ä¹å¥½å¨ç»éæ两个好å¤ï¼ä½¿ç¨å¨ç»æ¶éè¦æ´å°çJava代ç ï¼æ´ä½ä¸çä¸å»æ´å¹²åå¨xmlä¸å®ä¹ï¼å个å¨ç»å±æ§ä¸ç®äºç¶ä¹æ´éä¸ï¼æ¹ä¾¿é 读ä¸ç»´æ¤æ¢ç¶æè¿æ ·ç好å¤ï¼æ们就å¼å§å¹²å§ãé¦å å¨xmlä¸åä¸é¢è¿æ ·å®ä¹ä¸ä¸ªå¨ç»éï¼R.anim.my_anim_setmyapp:customProp2=""myapp:customProp3="%"android:duration=""android:fillAfter="true"/>ç¶åï¼æ们æç §å¸¸çæ¥ï¼å¨Java代ç ä¸è¿æ ·æ¥å è½½æ们å®ä¹çxmlå¨ç»éï¼AnimationSetset=(AnimationSet)AnimationUtils.loadAnimation(this,R.anim.my_anim_set);effectView.startAnimation(set);ä½æ¯ï¼æ±æï¼ä¸é¢ç代ç æ¯ä¸æ£ç¡®æ§è¡ï¼è¿è¡èµ·æ¥ç¨åºä¼ç´æ¥ç»æ¢ãé£ä»ä¹åå å¢ï¼æ¥çAnimationUtils.loadAnimationæºä»£ç æ们ç¥éï¼å¨å ¶ä»xmlè½½å ¥å¨ç»ç±»çæ¶åï¼åªè®¤alphaãscaleãrotateãtranslateè¿å 个SDKèªå¸¦çå¨ç»ç±»ï¼èæ们åå ¥çèªå®ä¹å¨ç»ç±»CustomAnimationä¼å¯¼è´å ¶æ¥Unknownanimationnameçå¼å¸¸ãå®æ¹SDKä¹æ²¡ææä¾è§£å³è¿ä¸ªé®é¢çå ¶ä»APIæ¹æ³ï¼é£ä¹æä¹è§£å³å¢ï¼å¾ç®åï¼åªéå¨åæçAnimationUtils.loadAnimationæºç ä¸æ¹å¨ä¸è¡ï¼ä»ClassLoaderè½½å ¥èªå®ä¹å¨ç»ç±»å³å¯ãå°å ¶æºç æ·è´è¿æ¥ï¼å®ç°ä¸ä¸ªèªå·±çloadAnimationæ¹æ³ï¼å¦ä¸ï¼OptAnimationLoader.javapublicclassOptAnimationLoader{ publicstaticAnimationloadAnimation(Contextcontext,intid)throwsResources.NotFoundException{ XmlResourceParserparser=null;try{ parser=context.getResources().getAnimation(id);returncreateAnimationFromXml(context,parser);}catch(XmlPullParserExceptionex){ Resources.NotFoundExceptionrnf=newResources.NotFoundException("Can'tloadanimationresourceID#0x"+Integer.toHexString(id));rnf.initCause(ex);throwrnf;}catch(IOExceptionex){ Resources.NotFoundExceptionrnf=newResources.NotFoundException("Can'tloadanimationresourceID#0x"+Integer.toHexString(id));rnf.initCause(ex);throwrnf;}finally{ if(parser!=null)parser.close();}}privatestaticAnimationcreateAnimationFromXml(Contextc,XmlPullParserparser)throwsXmlPullParserException,IOException{ returncreateAnimationFromXml(c,parser,null,Xml.asAttributeSet(parser));}privatestaticAnimationcreateAnimationFromXml(Contextc,XmlPullParserparser,AnimationSetparent,AttributeSetattrs)throwsXmlPullParserException,IOException{ Animationanim=null;//Makesureweareonastarttag.inttype;intdepth=parser.getDepth();while(((type=parser.next())!=XmlPullParser.END_TAG||parser.getDepth()>depth)&&type!=XmlPullParser.END_DOCUMENT){ if(type!=XmlPullParser.START_TAG){ continue;}Stringname=parser.getName();if(name.equals("set")){ anim=newAnimationSet(c,attrs);createAnimationFromXml(c,parser,(AnimationSet)anim,attrs);}elseif(name.equals("alpha")){ anim=newAlphaAnimation(c,attrs);}elseif(name.equals("scale")){ anim=newScaleAnimation(c,attrs);}elseif(name.equals("rotate")){ anim=newRotateAnimation(c,attrs);}elseif(name.equals("translate")){ anim=newTranslateAnimation(c,attrs);}else{ try{ anim=(Animation)Class.forName(name).getConstructor(Context.class,AttributeSet.class).newInstance(c,attrs);}catch(Exceptionte){ thrownewRuntimeException("Unknownanimationname:"+parser.getName()+"error:"+te.getMessage());}}if(parent!=null){ parent.addAnimation(anim);}}returnanim;}}è¿æ ·ï¼ä½¿ç¨OptAnimationLoader.loadAnimationæ¹æ³å°±å¯ä»¥ä»xmlä¸è½½å ¥å å«èªå®ä¹å¨ç»çå¨ç»éäºã