日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

用方面清理代码

發(fā)布時間:2023/12/3 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用方面清理代码 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
在我以前的文章中,我描述了字母轉(zhuǎn)換,并且提到了我們使用AspectJ解決了該任務(wù),但是我沒有提及AspectJ的工作原理以及一般性的方面。 因此,在接下來的幾行中,我將解釋:
  • 什么是面向方面的編程,為什么我們需要它
  • 什么是AspectJ
  • 將AspectJ與Spring結(jié)合使用(配置AspectJ和spring一起工作)
  • 我將解釋以前帖子中示例的各個方面。

什么是面向方面的編程以及我們?yōu)槭裁葱枰?/strong>

在軟件開發(fā)過程中,我們可以使用不同的編程范例,例如OOP(面向?qū)ο缶幊?#xff09;或POP(面向過程編程)。
今天,我們大多數(shù)人在軟件開發(fā)過程中使用面向?qū)ο蟮木幊谭椒▉斫鉀Q現(xiàn)實生活中的問題。

但是在我們的工作中,我們經(jīng)常遇到一些代碼,這些代碼貫穿我們的代碼庫,破壞了其模塊性并使它變得骯臟。

這部分代碼通常沒有業(yè)務(wù)價值,但是我們需要它們來解決問題。
例如,我們可以看一下數(shù)據(jù)庫事務(wù)。

事務(wù)對于我們的軟件非常重要,因為它們要注意數(shù)據(jù)的一致性。 啟動和處理事務(wù)的代碼對于我們的應(yīng)用程序非常重要,但是它用于技術(shù)性工作(啟動,提交和回滾事務(wù))。 這些東西使得很難理解代碼的真正含義(查看代碼的實際業(yè)務(wù)價值)。

當然,我不會在如何使用方面處理事務(wù)方面做任何示例,因為有很多框架會代替我們來處理事務(wù)。 我剛剛提到了事務(wù),因為您可能知道如何使用簡單的JDBC API將數(shù)據(jù)插入數(shù)據(jù)庫。

因此,為了使代碼更整潔,我們將使用設(shè)計模式,這是解決問題的好方法。 但是有時候使用設(shè)計模式也不會導(dǎo)致我們找到簡單的解決方案,而我們大多數(shù)人會訴諸于更簡單的解決方案,從而產(chǎn)生“骯臟”的代碼。

在這種情況下,我們應(yīng)該有機會采用面向方面的方法來解決問題。 在考慮AOP時,我們不應(yīng)該考慮對我們來說是全新的東西,而應(yīng)該將AOP視為對OOP的補充。 AOP可以簡化代碼模塊化,使代碼更整潔,并使我們更容易,更快地了解應(yīng)用程序的某些部分應(yīng)該做什么。

AOP引入了一些新概念,這將使我們更容易進行代碼調(diào)制。 如果我們想有效地使用Aspects,我們需要了解其基本原理和術(shù)語。
當我們開始使用AOP時,我們將遇到一個新的終端:

  • 橫切關(guān)注點是應(yīng)該在單獨的模塊中移動的代碼(即用于處理交易的代碼)。
  • 方面,它是包含關(guān)注點的模塊。
  • 切入點,我們可以將其視為指針,它將指示何時應(yīng)運行相應(yīng)的代碼
  • 建議,它包含一個代碼,當?shù)竭_某個連接點時應(yīng)運行該代碼。
  • 內(nèi)部類型聲明,允許修改類結(jié)構(gòu)。
  • 方面編織是協(xié)調(diào)與系統(tǒng)其余部分集成的機制。

我將在示例中最后說明它們是什么以及如何使用它們。

什么是AspectJ

AspectJ是Java編程語言的擴展,它允許在Java編程語言中使用AOP概念。

使用AspectJ時,無需在現(xiàn)有代碼中進行任何更改。

AspectJ使用稱為Aspect的新結(jié)構(gòu)擴展了Java,在AspectJ 5之后,您可以使用基于注釋的開發(fā)樣式。

AspectJ和Spring

Spring框架已經(jīng)提供了自己的AOP實現(xiàn)。 Spring AOP是比AspectJ更簡單的解決方案,但它不如AspectJ強大。 因此,如果要在Spring應(yīng)用程序中使用方面,在選擇AspectJ進行工作之前,應(yīng)該熟悉Spring AOP的可能性。

在我們看到使用Aspect的示例之前,我將向您展示如何將AspectJ與Spring集成以及如何配置Tomcat以使其能夠在Spring中運行AspectJ應(yīng)用程序。 在此示例中,我使用了方面的LTW(加載時間編織)。

因此,我將首先從Spring開始解釋如何做。 很簡單,只需在應(yīng)用程序配置文件中添加下一行:

<context:load-time-weaver aspectj-weaving="autodetect"/>

這就是彈簧配置所要做的全部工作。

下一步是Tomcat的配置。 我們需要為應(yīng)用程序定義新的類加載器。 該類加載器需要能夠進行加載時編織,因此我們使用:

<loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader" />

加載程序必須在Tomcat類路徑中,然后才能使用。
當然,為了使此工作有效,我們需要創(chuàng)建aop.xml文件。 該文件包含將在類轉(zhuǎn)換過程中由類加載器使用的指令。 這是我用于字母轉(zhuǎn)換的aop.xml文件的示例。

<aspectj><weaver options="-Xset:weaveJavaxPackages=true"><!-- only weave classes in our application-specific packages --><include within="ba.codecentric.medica.model.*" /><include within="ba.codecentric.medica..*.service.*" /><include within="ba.codecentric.medica.controller..*" /><include within="ba.codecentric.medica.utils.ModelMapper" /><include within="ba.codecentric.medica.utils.RedirectHelper" /><include within="ba.codecentric.medica.aop.aspect.CharacterConvertionAspect" /><include within="ba.codecentric.medica.security.UserAuthenticationProvider" /><include within="ba.codecentric.medica.wraper.MedicaRequestWrapper"/></weaver><aspects><!-- weave in just this aspect --><aspect name="ba.codecentric.medica.aop.aspect.CharacterConversionAspect" /></aspects> </aspectj>

對于愿意嘗試AspectJ的所有人來說,最后一個xml文件最為有趣。 它指示AspectJ編織過程。
編織器部分包含有關(guān)應(yīng)編織的信息。 因此,此文件將在其中包含所有類:

  • ba.codecentric.medica.model。*
  • ba.codecentric.medica .. *。service。*
  • ba.codecentric.medica.controller .. *
  • ba.codecentric.medica.utils.ModelMapper
  • ba.codecentric.medica.utils.RedirectHelper
  • ba.codecentric.medica.aop.aspect.CharacterConvertionAspect
  • ba.codecentric.medica.security.UserAuthenticationProvider
  • ba.codecentric.medica.wraper.MedicaRequestWrapper

因此,第一行包括模型包中的所有類。 第二個類包括所有類,它們是ba.codecentric.medica包(即ba.codecentric.medica.hospitalisation.service)內(nèi)的service子包的一部分。 第三個包括控制器組件下方的所有內(nèi)容。 其余各行包括指定的類。
選項屬性定義在編織過程中應(yīng)使用的附加選項。 因此,在此示例中-Xset:weaveJavaxPackages = true指示AspectJ也編織Java包。 方面部分包含將在編織過程中使用的方面的列表。 有關(guān)使用xml配置的更多信息,請參見AspectJ文檔 。

使用示例AspectJ


我更喜歡使用注釋,因此下一個示例將向您展示如何將AspectJ與注釋一起使用。 從AspectJ 5版本開始,可以使用AspectJ進行注釋驅(qū)動的編程。這是一些完整方面的代碼,其中包含用于字母轉(zhuǎn)換的注意事項。

package ba.codecentric.medica.aop.aspect;import java.util.List; import java.util.Map;import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect;import ba.codecentric.medica.utils.CharacterConverter; import ba.codecentric.medica.utils.ContextHelper; import ba.codecentric.medica.utils.LanguageHelper;/*** Aspect used for transformation characters from one alphabet to another. * * @author igor**/ @Aspect public class CharacterConvertionAspect {private static Log LOG = LogFactory.getLog(CharacterConvertionAspect.class);public int getConvertTo() {return getLanguageHelper().getConvertTo();}protected LanguageHelper getLanguageHelper() {return ContextHelper.getBean("languageHelper");}public CharacterConvertionAspect() {LOG.info("Character converter aspect created");}@SuppressWarnings("rawtypes")@Around("execution(public java.lang.String ba.codecentric.medica.model..*.get*(..)) && !cflow(execution(* ba.codecentric.medica.controller..*.*(..))) && !cflow(execution(public void ba.codecentric.medica..*.service..*.*(..))) && !cflow(execution(* ba.codecentric.medica.security.UserAuthenticationProvider.*(..)))")public Object convertCharacters(ProceedingJoinPoint pjp) throws Throwable {LOG.info("Character conversion trigered");Object value = pjp.proceed();if (value instanceof String) {LOG.info("Convert:" + value);Signature signature = pjp.getSignature();Class type = signature.getDeclaringType();String methodName = signature.getName();Map<Class, List<string&lgt;&lgt; skipConvertionMap = getBlackList();if(skipConvertionMap.containsKey(type)){List<string&lgt; list = skipConvertionMap.get(type);if(list == null || list.contains(methodName)){LOG.info("Value will not be converted because it is on blacklist");return value;}}return getConverter().convertCharacters((String) value, getConvertTo());}LOG.info("Convertion will not be performed (" + value + ")");return value;}@Around("execution(public void ba.codecentric.medica.model..*.set*(java.lang.String))")public Object convertCharactersToLat(ProceedingJoinPoint pjp) throws Throwable {Object value = pjp.getArgs()[0];LOG.info("Converting value:" + value + ", before persisting");if (value instanceof String){value= getConverter().convertCharacters((String)value, CharacterConverter.TO_LAT);}return pjp.proceed(new Object[]{value});}/*** Convert parameter to Latin alphabet* * @param pjp* @return* @throws Throwable*/@Around("execution(public * ba.codecentric.medica.wraper.MedicaRequestWrapper.getParameter*(..))")public Object convertParametersToLat(ProceedingJoinPoint pjp) throws Throwable {Object value = pjp.proceed();return getConverter().convert(value, CharacterConverter.TO_LAT);}/*** If result of the invocation is String, it should be converted to chosen alphabet.* * @param jp* @return converted value* @throws Throwable*/@Around("execution(* ba.codecentric.medica.controller..*.*(..))")public Object procedWithControllerInvocation(ProceedingJoinPoint jp) throws Throwable {Object value = jp.proceed();return getConverter().convert(value, getConvertTo());}public CharacterConverter getConverter() {return ContextHelper.getBean("characterConverter");}@SuppressWarnings("rawtypes")public Map<Class,List<string&lgt;&lgt; getBlackList(){return ContextHelper.getBean("blackList");}}

首先,我們可以看到該類使用@Aspect注釋進行了注釋。 這表明此類實際上是一個方面。 Aspect是一種包含類似橫切關(guān)注點的構(gòu)造。 因此,我們可以將其視為包含交叉代碼的模塊,并定義何時使用代碼以及如何使用。

@Around("execution(public void ba.codecentric.medica.model..*.set*(java.lang.String))") public Object convertCharactersToLat(ProceedingJoinPoint pjp) throws Throwable {Object value = pjp.getArgs()[0];LOG.debug("Converting value:" + value + ", before persisting");if (value instanceof String) {value = getConverter().convertCharacters((String) value, CharacterConverter.TO_LAT);}return pjp.proceed(new Object[] { value }); }

這是一種使用@Around注釋進行注釋的方法。 周圍注釋用于表示周圍建議。 我已經(jīng)提到過,建議是包含跨領(lǐng)域代碼的地方。 在此示例中,我僅使用了“周圍”建議,但是除了在返回之前,之后,之后和引發(fā)建議之后還有其他建議。 除了周圍的所有建議,都不應(yīng)有返回值。 注釋周圍的內(nèi)容定義了何時編織建議中的代碼。 當我們定義切入點時,也可以做到這一點。 在此示例中,我沒有使用切入點來定義連接點,因為它是簡單的方面。 使用切入點注釋,您可以定義真正的魯棒連接點。 在這種情況下,將在設(shè)置只有一個類型為String的參數(shù)的實體bean的值期間執(zhí)行建議。
在上面的示例中,ProcidingJoinPoint pjp提供了連接點,因此在此示例中,它是實體bean的setter方法。 發(fā)送到實體設(shè)置器方法的對象的值將首先轉(zhuǎn)換,然后將使用轉(zhuǎn)換后的值調(diào)用設(shè)置器方法。 如果我不使用方面,我的代碼可能如下所示:

public void setJmbg(String jmbg) {this.jmbg = getConverter().convertCharacters(jmbg, CharacterConverter.TO_LAT); }

我已經(jīng)說過,在此示例中,我使用LTW。 因此,在接下來的幾行中,我將嘗試簡要地解釋編織過程。 編織是其中類以定義的方面進行轉(zhuǎn)換的過程。 在下一張圖片中,您可以看到編織過程的圖示。

為了更好地理解編織,在這種情況下,可以將其視為圍繞調(diào)用方法的代碼注入。

結(jié)論


因此,在此示例中,我僅介紹了使用AspectJ進行方面編程的一些基本原理。 這方面幫助我保持了代碼的整潔。 使用方面的結(jié)果是跨界代碼與實際業(yè)務(wù)價值代碼的清晰分離。 控制器,服務(wù)和實體Bean保持整潔,并且將技術(shù)代碼提取到單獨的模塊中,使您可以更輕松地理解和維護代碼。 有關(guān)定義切入點和AspectJ項目常規(guī)的更多詳細信息,您可以在項目頁面上看到。

祝您編程愉快,別忘了分享!

參考:在Igor Madjeric博客上,我們的JCG合作伙伴 Igor Madjeric 提供了一些方面干凈的代碼 。


翻譯自: https://www.javacodegeeks.com/2012/10/clean-code-with-aspects.html

總結(jié)

以上是生活随笔為你收集整理的用方面清理代码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产日产久久高清欧美一区 | 久久中文娱乐网 | 日本少妇一区二区三区 | 国产精品成人网站 | 神马午夜激情 | 中文字幕黄色片 | 激情网页 | 青青草激情视频 | 日本少妇ⅹxxxxx视频 | 18禁男女爽爽爽午夜网站免费 | 午夜www| 一级黄色片免费观看 | 女生抠逼视频 | 黄色国产一区二区 | 一级黄色裸体片 | ass极品国模人体欣赏 | 亚洲精品男人的天堂 | 精品久久一二三区 | 国产欧美一区二区三区白浆喷水 | 污污软件在线观看 | 伊人小视频 | 国产91在线播放九色 | 国产原创91 | 欧洲精品一区二区三区久久 | 18国产免费视频 | 一区二区三区麻豆 | 黄色大片在线免费观看 | 日本在线观看 | 99re国产| 黄色影音 | 国内偷拍久久 | 国产人妻精品一区二区三区不卡 | 伊人久久精品一区二区三区 | 国产无遮挡又黄又爽在线观看 | 亚洲成人伦理 | 天天操人人爽 | 国产精品久久久久久久蜜臀 | 欧美日韩国产综合在线 | 欧美一区二区三区视频在线观看 | 一级片视频免费看 | 国产日产精品一区二区三区 | 99精品视频在线免费观看 | www.亚洲综合 | av黄页| 国产日韩av一区二区 | 欧美天堂| 国产精品白丝喷水在线观看 | 男人免费视频 | 九草在线 | 国产精品久久久久久久久久久久 | 性欧美18一19性猛交 | 成人午夜精品福利 | 欧美久久久一区二区三区 | 国产亚洲精品久久久久四川人 | 亲嘴扒胸摸屁股免费视频日本网站 | 国产亚洲一区二区三区不卡 | 欧美色视频一区二区三区 | 久久免费精品视频 | 老妇女玩小男生毛片 | 久久精品国产亚洲AV成人婷婷 | 在线观看视频日韩 | 开心激情深爱 | 北条麻妃在线一区 | 中文字幕无码精品亚洲35 | 黄色三级生活片 | 亚洲视频你懂的 | 久久av免费观看 | 国产调教av | 特级毛片在线播放 | 男人天堂新地址 | 成人在线短视频 | 欧美一区二区三区在线 | 奇米影视首页 | 色黄啪啪网 | 欧美xx视频 | 韩国不卡av | 快色网站 | 使劲插视频 | 999免费| 九月色婷婷 | 欧美一级做a爰片免费视频 成人激情在线观看 | 免费成年人视频在线观看 | 中国字幕一色哟哟 | 天天插天天操天天干 | 影音先锋黄色资源 | 日韩高清精品免费观看 | 一区二区久久精品66国产精品 | 黄色麻豆视频 | 粉嫩aⅴ一区二区三区四区五区 | 天天影视色 | 亚洲综合日韩精品欧美综合区 | 天天燥日日燥 | 欧美一二区 | 成人三级在线看 | 香蕉福利 | 精品国偷自产在线 | 久久久久久久久久久久久久久 | 日韩视频在线观看一区 | 和美女啪啪 |