路由器统一登录网站,游戏平台网站建设,专业的聊城网站优化,排名网安卓清理垃圾清理代码在我以前的文章中#xff0c;我描述了字母转换#xff0c;并且提到了我们使用AspectJ来解决该任务#xff0c;但是我没有提及AspectJ的工作原理和一般性方面。 因此#xff0c;在接下来的几行中#xff0c;我将解释#xff1a; 什么是面向方面的编程… 安卓清理垃圾清理代码 在我以前的文章中我描述了字母转换并且提到了我们使用AspectJ来解决该任务但是我没有提及AspectJ的工作原理和一般性方面。 因此在接下来的几行中我将解释 什么是面向方面的编程为什么我们需要它 什么是AspectJ 将AspectJ与Spring结合使用配置AspectJ和spring一起工作 我将解释以前帖子中示例的各个方面。 什么是面向方面的编程以及我们为什么需要它 在软件开发过程中我们可以使用不同的编程范例例如OOP面向对象编程或POP面向过程编程。 今天我们大多数人在软件开发过程中使用面向对象的编程方法来解决现实生活中的问题。 但是在我们的工作中我们经常遇到一些代码这些代码贯穿我们的代码库破坏了其模块性并使它变得肮脏。 这部分代码通常没有业务价值但是我们需要它们来解决问题。 例如我们可以看一下数据库事务。 事务对于我们的软件非常重要因为它们要注意数据的一致性。 启动和处理事务的代码对于我们的应用程序非常重要但是它用于技术性工作启动提交和回滚事务。 这些东西使得很难理解代码的真正含义查看代码的实际业务价值。 当然我不会在如何使用方面处理事务方面做任何示例因为有很多框架会代替我们来处理事务。 我刚刚提到了事务因为您可能知道如何使用简单的JDBC API将数据插入数据库。 因此为了使代码更整洁我们将使用设计模式这是解决问题的一种好方法。 但是有时候使用设计模式也不会导致我们找到简单的解决方案并且我们大多数人都会诉诸于更简单的解决方案从而产生“肮脏”的代码。 在这种情况下我们应该有机会采用面向方面的方法来解决问题。 当我们考虑AOP时我们不应该考虑对我们来说是全新的东西而应该考虑将AOP作为OOP的补充。 AOP可以简化代码模块化使代码更整洁并使我们更容易更快地了解应用程序的某些部分应该做什么。 AOP引入了一些新概念这将使我们更容易进行代码调制。 如果我们想有效地使用Aspects我们需要了解其基本原理和术语。 当我们开始使用AOP时我们将遇到一个新的终端 横切关注点是应该在单独的模块中移动的代码即用于处理交易的代码。 方面它是一个包含关注点的模块。 切入点我们可以将其视为指针它将指示何时应运行相应的代码 建议它包含一个代码当到达某个连接点时应运行该代码。 内部类型声明允许修改类结构。 方面编织是协调与系统其余部分集成的机制。 我将在示例中最后说明它们是什么以及如何使用它们。 什么是AspectJ AspectJ是Java编程语言的扩展它允许在Java编程语言中使用AOP概念。 使用AspectJ时无需在现有代码中进行任何更改。 AspectJ使用称为Aspect的新结构扩展了Java在AspectJ 5之后您可以使用基于注释的开发样式。 AspectJ和Spring Spring框架已经提供了自己的AOP实现。 Spring AOP比AspectJ更简单的解决方案但它不如AspectJ强大。 因此如果您想在Spring应用程序中使用方面那么在选择AspectJ进行工作之前应该熟悉Spring AOP的可能性。 在我们看到使用Aspect的示例之前我将向您展示如何将AspectJ与Spring集成以及如何配置Tomcat以使其能够在Spring中运行AspectJ应用程序。 在此示例中我使用了方面的LTW加载时间编织。 因此我将首先从Spring开始解释如何做。 很简单只需在应用程序配置文件中添加下一行 context:load-time-weaver aspectj-weavingautodetect/ 这就是在弹簧配置中需要做的所有事情。 下一步是Tomcat的配置。 我们需要为应用程序定义新的类加载器。 该类加载器需要能够进行加载时编织因此我们使用 loader loaderClassorg.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader / 加载程序必须在Tomcat类路径中然后才能使用。 当然为了使此工作有效我们需要创建aop.xml文件。 该文件包含将在类转换过程中由类加载器使用的指令。 这是我用于字母转换的aop.xml文件的示例。 aspectjweaver options-Xset:weaveJavaxPackagestrue!-- only weave classes in our application-specific packages --include withinba.codecentric.medica.model.* /include withinba.codecentric.medica..*.service.* /include withinba.codecentric.medica.controller..* /include withinba.codecentric.medica.utils.ModelMapper /include withinba.codecentric.medica.utils.RedirectHelper /include withinba.codecentric.medica.aop.aspect.CharacterConvertionAspect /include withinba.codecentric.medica.security.UserAuthenticationProvider /include withinba.codecentric.medica.wraper.MedicaRequestWrapper//weaveraspects!-- weave in just this aspect --aspect nameba.codecentric.medica.aop.aspect.CharacterConversionAspect //aspects
/aspectj 对于愿意尝试AspectJ的所有人来说最后一个xml文件最为有趣。 它指示AspectJ编织过程。 编织器部分包含有关应编织的信息。 因此此文件将在其中包括所有类 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内的service子包的一部分。 第三个包括控制器软件包下面的所有内容。 其余各行包括指定的类。 选项属性定义在编织过程中应使用的附加选项。 因此在此示例中-XsetweaveJavaxPackages true指示AspectJ也编织Java包。 方面部分包含将在编织过程中使用的方面的列表。 有关使用xml配置的更多信息请参见AspectJ文档 。 使用示例AspectJ 我更喜欢使用注释因此下一个示例将向您展示如何将AspectJ与注释一起使用。 从AspectJ 5版本开始可以使用AspectJ进行注释驱动的编程。这是一些完整方面的代码其中包含用于字母转换的注意事项。 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();MapClass, Liststringlgt;lgt; skipConvertionMap getBlackList();if(skipConvertionMap.containsKey(type)){Liststringlgt; 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 MapClass,Liststringlgt;lgt; getBlackList(){return ContextHelper.getBean(blackList);}} 首先我们可以看到该类使用Aspect注释进行了注释。 这表明此类实际上是一个方面。 Aspect是一种包含类似跨领域关注点的构造。 因此我们可以将其视为包含交叉代码的模块并定义何时使用代码以及如何使用。 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注释进行注释的方法。 周围注释用于表示周围建议。 我已经提到过建议是包含跨领域代码的地方。 在此示例中我仅使用了“周围”建议但是除了在返回之前之后之后和引发建议之后还有其他建议。 除了周围的所有建议都不应有返回值。 注释周围的内容定义了何时编织建议中的代码。 当我们定义切入点时也可以做到这一点。 在此示例中我没有使用切入点来定义连接点因为它是简单的方面。 使用切入点注释您可以定义真正的鲁棒连接点。 在这种情况下将在设置只有一个String类型参数的实体bean的设置值期间执行建议。 在上面的示例中ProcidingJoinPoint pjp提供了连接点因此在此示例中它是实体bean的setter方法。 发送到实体设置器方法的对象的值将首先转换然后将使用转换后的值调用设置器方法。 如果我不使用方面我的代码可能看起来像 public void setJmbg(String jmbg) {this.jmbg getConverter().convertCharacters(jmbg, CharacterConverter.TO_LAT);
} 我已经说过在此示例中我使用LTW。 因此在接下来的几行中我将尝试简要地解释编织过程。 编织是其中类以定义的方面进行转换的过程。 在下一张图片中您可以看到编织过程的图示。 为了更好地理解编织在这种情况下可以将其视为围绕调用方法的代码注入。 结论 因此在此示例中我仅介绍了使用AspectJ进行方面编程的一些基本原理。 这方面帮助我保持了代码的整洁。 使用方面的结果是跨界代码与实际业务价值代码的清晰分离。 控制器服务和实体bean保持整洁并且将技术代码提取到单独的模块中使您可以更轻松地理解和维护代码。 有关定义切入点和AspectJ项目常规的更多详细信息您可以在项目页面上看到。 祝您编程愉快别忘了分享 参考在Igor Madjeric博客上我们的JCG合作伙伴 Igor Madjeric 提供了一些方面干净的代码 。 翻译自: https://www.javacodegeeks.com/2012/10/clean-code-with-aspects.html安卓清理垃圾清理代码