安卓清理垃圾清理代码_用方面清理代码

安卓清理垃圾清理代码

在我以前的文章中,我描述了字母转换,并且提到了我们使用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-weaving="autodetect"/>

这就是在弹簧配置中需要做的所有事情。

下一步是Tomcat的配置。 我们需要为应用程序定义新的类加载器。 该类加载器需要能够进行加载时编织,因此我们使用:

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

加载程序必须在Tomcat类路径中,然后才能使用。
当然,为了使此工作有效,我们需要创建aop.xml文件。 该文件包含将在类转换过程中由类加载器使用的指令。
这是我用于字母转换的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编织过程。
编织器部分包含有关应编织的信息。 因此,此文件将在其中包括所有类:

  • 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子包的一部分。 第三个包括控制器软件包下面的所有内容。 其余各行包括指定的类。
选项属性定义在编织过程中应使用的附加选项。 因此,在此示例中-Xset:weaveJavaxPackages = 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();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是一种包含类似跨领域关注点的构造。 因此,我们可以将其视为包含交叉代码的模块,并定义何时使用代码以及如何使用。

@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

安卓清理垃圾清理代码

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

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

相关文章

最大功率点跟踪_ADI公司推出集成最大功率点跟踪和I2C的80V降压升压电池充电控制器...

中国&#xff0c;北京 – Analog Devices, Inc. (ADI)&#xff0c;今日宣布推出LT8491降压-升压电池充电控制器&#xff0c;该控制器具有最大功率点跟踪(MPPT)、温度补偿和I2C接口等特性&#xff0c;适用于遥测和控制。该器件的工作电压可高于、低于或等于经调节的电池浮充电压…

VIM 编码配置

在 Vim 中&#xff0c;有四个与编码有关的选项&#xff0c;它们是&#xff1a;fileencodings、fileencoding、encoding 和 termencoding。在实际使用中&#xff0c;任何一个选项出现错误&#xff0c;都会导致出现乱码。因此&#xff0c;每一个 Vim 用户都应该明确这四个选项的含…

关于摄像头的一些零碎知识

项目上需要用到读取摄像头的帧数据&#xff0c;在对视频帧做算法处理。简单了解了一下摄像头的分类和如何读取。 1、总体上来说&#xff0c;在win平台下面摄像头数据采集无外乎两种方式vfw和direct show。其中vfw是不依赖于sdk的&#xff0c;只要有系统api即可实现摄像头数据的…

MQTT和Java入门

MQTT&#xff08;MQ遥测传输&#xff09;是一种轻量级的发布/订阅消息传递协议。 MQTT在物联网应用程序中得到了广泛使用&#xff0c;因为它被设计为在占用空间小的系统上运行在远程位置。 MQTT 3.1是OASIS标准&#xff0c;您可以在http://mqtt.org/上找到所有信息。 本文将指…

函数的命名空间

# 函数进阶 # a 1 # def func(): # print(a) # func()# 命名空间和作用域 # print() # input() # list # tuple#命名空间 有三种 #内置命名空间 —— python解释器# 就是python解释器一启动就可以使用的名字存储在内置命名空间中# 内置的名字在启动解释器的时候被加载进内…

在Linux环境下mysql的root密码忘记解决方法

原创作品&#xff0c;允许转载&#xff0c;转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://lxsym.blog.51cto.com/1364623/477027 MySQL密码的恢复方法之一 1&#xff0e;首先确认服务器出于安全的状态&#xff0c;也就是没有人能…

史迪仔的原型_星际宝贝三个版本对比,莉罗抛弃史迪仔,童年真的回不去了

星际宝贝这部动漫大家应该不陌生&#xff0c;以前为了看这部动漫&#xff0c;经常蹲着点打开电视&#xff0c;看到莉罗和626一天的烦恼都没了。星际宝贝可以说风靡全球&#xff0c;所以日漫还有国漫也不甘落后&#xff0c;纷纷和迪士尼完成了自己的星际宝贝&#xff0c;来跟宅编…

warning C4091: “typedef ”: 没有声明变量时忽略“_matcher”的左侧

C 警告 warning C4091: “typedef ”: 没有声明变量时忽略“_matcher”的左侧 typedef struct _matcher {int Idx1;int Idx2;double dis; };修改方法&#xff1a;删掉typedef &#xff0c;这是C语言的结构体&#xff0c;C 会自动分配。

C# 获取对象 大小 Marshal.SizeOf (sizeof 只能在不安全的上下文中使用)

C# 能否获取一个对象所占内存的大小&#xff1f; 今日&#xff0c;在项目重构的时候忽然想到一个问题&#xff0c;一个类哪些成员的增加&#xff0c;会影响一个类所占内存的大小&#xff1f;C#有没有办法知道一个对象占多少内存呢&#xff1f; 第一个问题&#xff1a;很快想到是…

警告warningC4018有符号/无符号不匹配

C警告 warning C4018: “<”: 有符号/无符号不匹配 警告代码如下&#xff1a;for (int i 0; i<matchePoints.size(); i){imagePoints1.push_back(keypoints1[matchePoints[i].Idx1].pt);imagePoints2.push_back(keypoints2[matchePoints[i].Idx2].pt);} 错误原因&…

tp5类的属性不存在_thinkPHP5.1框架中Request类四种调用方式示例

本文实例讲述了thinkPHP5.1框架中Request类四种调用方式。分享给大家供大家参考&#xff0c;具体如下&#xff1a;1. 传统调用访问方式&#xff1a;http://127.0.0.1/demo/demo3/test?namekk&age22/*** Created by PhpStorm.* User: 10475* Date: 2018/8/27* Time: 22:59*…

设置 Linux 的 LD_LIBRARY_PATH 变量

我们在ubuntu图形界面下用eclipse写了一个动态库&#xff0c;到centos下调用时出现错误&#xff0c; error while loading shared libraries: libmysqlclientso.so.0: cannot open shared object file: No such file or directory 以为没装mysql-client&#xff0c;因为ub…

javaone_JavaOne 2012覆盖率

javaone年度Java盛会JavaOne于9月30日至10月4日在旧金山举行。 进行了许多有趣的演示&#xff0c;再次证明了健康的Java生态系统。 Java Code Geeks未能参加会议&#xff0c;但是我们的JCG合作伙伴Dustin Marx出席了会议&#xff0c;并且慷慨地提供了有关该事件的完整报道&…

第十二章 泛型

目录&#xff1a; 12.1 FCL中的泛型 12.2 泛型基础结构 12.3 泛型接口 12.4 泛型委托 12.5 委托和接口的逆变和协变泛型类型实参 12.6 泛型方法 12.7 泛型和其他成员 12.8 可验证性和约束 泛型时CLR和编程语言提供的一种特殊机制&#xff0c;它支持另一种形式的代码重用&#x…

memset()函数详解

1、头文件C中为<memory.h> 或 <string.h>C中为<cstring> 2、原型及作用 void *memset(void *s,int c,size_t n)其中&#xff0c;s是一个指针或数组&#xff0c;c是赋给s的值&#xff0c;n是将修改的s的长度&#xff0c;即s的前n个字节。作用&#xff1a;将已…

jq 如何让点击其他地方隐藏_详解jQuery除指定区域外点击任何地方隐藏DIV功能

本文主要介绍了jQuery除指定区域外点击任何地方隐藏p的相关资料,代码简单易懂&#xff0c;非常不错&#xff0c;具有参考借鉴价值&#xff0c;需要的朋友可以参考下&#xff0c;希望能帮助到大家。具体代码如下所示&#xff1a;$(body).click(function(e) {var target $(e.tar…

linux系统编程之进程(八):守护进程详解及创建,daemon()使用

一&#xff0c;守护进程概述 Linux Daemon&#xff08;守护进程&#xff09;是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务&#xff0c;不是对整个系统就是对某个用户程序提供服务…

您还在调试吗?

调试是“以交互方式运行程序/方法&#xff0c;在每个语句后中断执行流程并显示……的过程。”简而言之&#xff0c;它是一种非常有用的技术……对于一个糟糕的程序员而言。 或仍然在用C编写过程代码的老程序员。面向对象的程序员从不调试其代码-他们编写单元测试。 我的意思是&…

RESTful规范

本文目录 什么是RESTful RESTful API设计 基于Django实现 什么是RESTful REST与技术无关&#xff0c;代表的是一种软件架构风格&#xff0c;REST是Representational State Transfer的简称&#xff0c;中文翻译为“表征状态转移”REST从资源的角度类审视整个网络&#xff0c;它…

反向输出dna序列_蛋白质序列反向(逆向)翻译成DNA序列-在线工具

请粘贴蛋白质序列&#xff0c;如果需要输入多个序列&#xff0c;请以fasta格式输入&#xff0c;输入总长度不超过2万个字符。>testACDEFGHIKLMNPQRSTVWY*推荐使用IE 8.0以上、chrome或者Firefox等浏览器。请输入该蛋白来源物种的密码子使用表(GCG格式)&#xff0c;下表示大肠…