1.springâAOPä¸äºå¡
2.Go能实现AOP吗?
3.Spring Boot 使用 AOP 防止重复提交
4.Spring源码插播一个创建代理对象的码设wrapIfNecessary()方法
5.面试官:你讲讲AOP与OOP有什么区别?
6.å¦ä½å®ä¹ä¸ä¸ªaopç»ä»¶
springâAOPä¸äºå¡
title: springââAOPä¸äºå¡.mddate: -- ::
categories: [Spring]
tags: [AOP,äºå¡]
toc: true
å ååºæºç ä¸æ¯è¾éç¹çå 个类ï¼
1ã<aop:before method="before" pointcut-ref="myMethods"/>å è£ æä¸ä¸ªadvisor
2ãAspectJAwareAdvisorAutoProxyCreatorï¼å½å®ä¾åææbeané½ä¼æ§è¡å°AspectJAwareAdvisorAutoProxyCreatorç±»
å®ä¼æ£æµbeanæ¯å¦advisor以åadviceåå¨ï¼å¦ææ就说æè¿ä¸ªbeanæåé¢ï¼æåé¢é£ä¹å°±ä¼çæ代ç
3ãjdkç代çï¼beanéé¢çææadvisorå å ¥å°proxyFactoryã
4ãjdkDynamicProxy invokeï¼æ¿å°beanéé¢çææInterceptorï¼ä¼å¾ªç¯proxyFactoryéé¢çææadvisor
éé¢æadviceï¼éé¢çadviceæ两ç§ç±»åï¼è¦ä¹æ¯adviceï¼è¦ä¹æ¯MethodInterceptorç±»åç
5ãå½ä»£ç对象è°ç¨æ¹å¼ï¼æ¯ä¸ä¸ªMethodInterceptorç±»åçç±»çé¾å¼è°ç¨è¿ç¨ï¼ç´å°å®¹å¨ç大å°åç´¢å¼ä¸è´çæ¶åè°ç¨JoinPointç®æ æ¹æ³
beforeï¼this.advice.before(),invocation.processd();
è£ é åæ°ï¼åé¢éé¢beforeæ¹æ³çmethod对象ï¼method.getParamterTypes()[0]
æç»ä¼æadviceå°è£ æMethodInterceptorç±»åç对象
ç¨åºæ§è¡çæ个ç¹å®ä½ç½®ï¼å¦ç±»å¼å§åå§ååãç±»åå§ååãç±»æ个æ¹æ³è°ç¨åãè°ç¨åãæ¹æ³æåºå¼å¸¸åãä¸ä¸ªç±»æä¸æ®µç¨åºä»£ç æ¥æä¸äºå ·æè¾¹çæ§è´¨çç¹å®ç¹ï¼è¿äºç¹ä¸çç¹å®ç¹å°±ç§°ä¸ºâè¿æ¥ç¹âãSpringä» æ¯ææ¹æ³çè¿æ¥ç¹ï¼å³ä» è½å¨æ¹æ³è°ç¨åãæ¹æ³è°ç¨åãæ¹æ³æåºå¼å¸¸æ¶ä»¥åæ¹æ³è°ç¨ååè¿äºç¨åºæ§è¡ç¹ç»å ¥å¢å¼ºãè¿æ¥ç¹ç±ä¸¤ä¸ªä¿¡æ¯ç¡®å®ï¼ç¬¬ä¸æ¯ç¨æ¹æ³è¡¨ç¤ºçç¨åºæ§è¡ç¹ï¼ç¬¬äºæ¯ç¨ç¸å¯¹ç¹è¡¨ç¤ºçæ¹ä½ã
æ¯ä¸ªç¨åºç±»é½æ¥æå¤ä¸ªè¿æ¥ç¹ï¼å¦ä¸ä¸ªæ¥æ两个æ¹æ³çç±»ï¼è¿ä¸¤ä¸ªæ¹æ³é½æ¯è¿æ¥ç¹ï¼å³è¿æ¥ç¹æ¯ç¨åºç±»ä¸å®¢è§åå¨çäºç©ãAOPéè¿âåç¹âå®ä½ç¹å®çè¿æ¥ç¹ãè¿æ¥ç¹ç¸å½äºæ°æ®åºä¸çè®°å½ï¼èåç¹ç¸å½äºæ¥è¯¢æ¡ä»¶ãåç¹åè¿æ¥ç¹ä¸æ¯ä¸å¯¹ä¸çå ³ç³»ï¼ä¸ä¸ªåç¹å¯ä»¥å¹é å¤ä¸ªè¿æ¥ç¹ãå¨Springä¸ï¼åç¹éè¿org.springframework.aop.Pointcutæ¥å£è¿è¡æè¿°ï¼å®ä½¿ç¨ç±»åæ¹æ³ä½ä¸ºè¿æ¥ç¹çæ¥è¯¢æ¡ä»¶ï¼Spring AOPçè§å解æå¼æè´è´£åç¹æ设å®çæ¥è¯¢æ¡ä»¶ï¼æ¾å°å¯¹åºçè¿æ¥ç¹ãå ¶å®ç¡®åå°è¯´ï¼ä¸è½ç§°ä¹ä¸ºæ¥è¯¢è¿æ¥ç¹ï¼å 为è¿æ¥ç¹æ¯æ¹æ³æ§è¡åãæ§è¡åçå æ¬æ¹ä½ä¿¡æ¯çå ·ä½ç¨åºæ§è¡ç¹ï¼èåç¹åªå®ä½å°æ个æ¹æ³ä¸ï¼æ以å¦æå¸æå®ä½å°å ·ä½è¿æ¥ç¹ä¸ï¼è¿éè¦æä¾æ¹ä½ä¿¡æ¯ã
å¢å¼ºæ¯ç»å ¥å°ç®æ ç±»è¿æ¥ç¹ä¸çä¸æ®µç¨åºä»£ç ï¼å¨Springä¸ï¼å¢å¼ºé¤ç¨äºæè¿°ä¸æ®µç¨åºä»£ç å¤ï¼è¿æ¥æå¦ä¸ä¸ªåè¿æ¥ç¹ç¸å ³çä¿¡æ¯ï¼è¿ä¾¿æ¯æ§è¡ç¹çæ¹ä½ãç»åæ§è¡ç¹æ¹ä½ä¿¡æ¯ååç¹ä¿¡æ¯ï¼æ们就å¯ä»¥æ¾å°ç¹å®çè¿æ¥ç¹ã
å¢å¼ºé»è¾çç»å ¥ç®æ ç±»ãå¦æ没æAOPï¼ç®æ ä¸å¡ç±»éè¦èªå·±å®ç°ææé»è¾ï¼èå¨AOPç帮å©ä¸ï¼ç®æ ä¸å¡ç±»åªå®ç°é£äºé横åé»è¾çç¨åºé»è¾ï¼èæ§è½çè§åäºå¡ç®¡ççè¿äºæ¨ªåé»è¾åå¯ä»¥ä½¿ç¨AOPå¨æç»å ¥å°ç¹å®çè¿æ¥ç¹ä¸ã
å¼ä»æ¯ä¸ç§ç¹æ®çå¢å¼ºï¼å®ä¸ºç±»æ·»å ä¸äºå±æ§åæ¹æ³ãè¿æ ·ï¼å³ä½¿ä¸ä¸ªä¸å¡ç±»åæ¬æ²¡æå®ç°æ个æ¥å£ï¼éè¿AOPçå¼ä»åè½ï¼æ们å¯ä»¥å¨æå°ä¸ºè¯¥ä¸å¡ç±»æ·»å æ¥å£çå®ç°é»è¾ï¼è®©ä¸å¡ç±»æ为è¿ä¸ªæ¥å£çå®ç°ç±»ã
ç»å ¥æ¯å°å¢å¼ºæ·»å 对ç®æ ç±»å ·ä½è¿æ¥ç¹ä¸çè¿ç¨ãAOPåä¸å°ç»å¸æºï¼å°ç®æ ç±»ãå¢å¼ºæå¼ä»éè¿AOPè¿å°ç»å¸æºå¤©è¡£æ ç¼å°ç¼ç»å°ä¸èµ·ãæ ¹æ®ä¸åçå®ç°ææ¯ï¼AOPæä¸ç§ç»å ¥çæ¹å¼ï¼
aãç¼è¯æç»å ¥ï¼è¿è¦æ±ä½¿ç¨ç¹æ®çJavaç¼è¯å¨ã
bãç±»è£ è½½æç»å ¥ï¼è¿è¦æ±ä½¿ç¨ç¹æ®çç±»è£ è½½å¨ã
cãå¨æ代çç»å ¥ï¼å¨è¿è¡æ为ç®æ 类添å å¢å¼ºçæåç±»çæ¹å¼ã
Springéç¨å¨æ代çç»å ¥ï¼èAspectJéç¨ç¼è¯æç»å ¥åç±»è£ è½½æç»å ¥ã
ä¸ä¸ªç±»è¢«AOPç»å ¥å¢å¼ºåï¼å°±äº§åºäºä¸ä¸ªç»æç±»ï¼å®æ¯èåäºåç±»åå¢å¼ºé»è¾ç代çç±»ãæ ¹æ®ä¸åç代çæ¹å¼ï¼ä»£çç±»æ¢å¯è½æ¯ååç±»å ·æç¸åæ¥å£çç±»ï¼ä¹å¯è½å°±æ¯åç±»çåç±»ï¼æ以æ们å¯ä»¥éç¨è°ç¨åç±»ç¸åçæ¹å¼è°ç¨ä»£çç±»ã
åé¢ç±åç¹åå¢å¼ºï¼å¼ä»ï¼ç»æï¼å®æ¢å æ¬äºæ¨ªåé»è¾çå®ä¹ï¼ä¹å æ¬äºè¿æ¥ç¹çå®ä¹ï¼Spring AOPå°±æ¯è´è´£å®æ½åé¢çæ¡æ¶ï¼å®å°åé¢æå®ä¹ç横åé»è¾ç»å ¥å°åé¢ææå®çè¿æ¥ç¹ä¸ã
advisorï¼ pointCut advice
ä¸ç±»åè½çå¢å¼º
aroundæ¹æ³éé¢ä»£ç åé¢
äºå¡åé¢
ç¼ååé¢
æ¥å¿åé¢
äºå¡ï¼Transactionï¼ï¼ä¸è¬æ¯æè¦åçææåçäºæ ãå¨è®¡ç®æºæ¯è¯ä¸æ¯æ访é®å¹¶å¯è½æ´æ°æ°æ®åºä¸åç§æ°æ®é¡¹çä¸ä¸ªç¨åºæ§è¡åå (unit)ãæ¯æ°æ®åºæä½çæå°å·¥ä½åå ï¼æ¯ä½ä¸ºå个é»è¾å·¥ä½åå æ§è¡çä¸ç³»åæä½ï¼è¿äºæä½ä½ä¸ºä¸ä¸ªæ´ä½ä¸èµ·åç³»ç»æ交ï¼è¦ä¹é½æ§è¡ãè¦ä¹é½ä¸æ§è¡ï¼äºå¡æ¯ä¸ç»ä¸å¯ååå²çæä½éåï¼å·¥ä½é»è¾åå ï¼ã
大è´æµç¨å½¢å¦
æ°æ®åºäºå¡æ¥æå 大ç¹æ§ï¼
äºå¡çå大ç¹æ§ï¼
äºå¡æ¯æ°æ®åºçé»è¾å·¥ä½åä½ï¼äºå¡ä¸å å«çåæä½è¦ä¹é½åï¼è¦ä¹é½ä¸å
äº å¡æ§è¡çç»æå¿ é¡»æ¯ä½¿æ°æ®åºä»ä¸ä¸ªä¸è´æ§ç¶æåå°å¦ä¸ä¸ªä¸è´æ§ç¶æãå æ¤å½æ°æ®åºåªå å«æåäºå¡æ交çç»ææ¶ï¼å°±è¯´æ°æ®åºå¤äºä¸è´æ§ç¶æãå¦ææ°æ®åºç³»ç» è¿è¡ä¸åçæ éï¼æäºäºå¡å°æªå®æ就被迫ä¸æï¼è¿äºæªå®æäºå¡å¯¹æ°æ®åºæåçä¿®æ¹æä¸é¨åå·²åå ¥ç©çæ°æ®åºï¼è¿æ¶æ°æ®åºå°±å¤äºä¸ç§ä¸æ£ç¡®çç¶æï¼æè è¯´æ¯ ä¸ä¸è´çç¶æã
ä¸ä¸ªäºå¡çæ§è¡ä¸è½å ¶å®äºå¡å¹²æ°ãå³ä¸ä¸ªäºå¡å é¨çæä½å使ç¨çæ°æ®å¯¹å ¶å®å¹¶åäºå¡æ¯é离çï¼å¹¶åæ§è¡çå个äºå¡ä¹é´ä¸è½äºç¸å¹²æ°ã
ä¹ç§°æ°¸ä¹ æ§ï¼æä¸ä¸ªäºå¡ä¸æ¦æ交ï¼å®å¯¹æ°æ®åºä¸çæ°æ®çæ¹åå°±åºè¯¥æ¯æ°¸ä¹ æ§çãæ¥ä¸æ¥çå ¶å®æä½ææ éä¸åºè¯¥å¯¹å ¶æ§è¡ç»ææä»»ä½å½±åã
个人ç解ï¼äºå¡å¨Springä¸æ¯åå©AOPææ¯æ¥å®ç°çï¼å¯ä»¥ä½ä¸ºAOPä¸çä¸ä¸ªäºå¡åé¢ãspringæºç 对äºå¡çå¤çé»è¾ï¼èªå·±ç 究å§ï¼
ORMæ¡æ¶ä¸ä»¥Mybatis为ä¾ï¼äºå¡å¤çå°±æ¯ç¨å°äºä¸ä¸ªç±»Transactionï¼é¨åæºç å¦ä¸
å¯ä»¥çåºTransaction管ççå°±æ¯ä¸ä¸ªconnectionï¼èconnectionæ们å¾æ¸ æ¥æ¯ä¸ç¨æ·ä¼è¯æé©çã
é£ä¹å ³ç³»å°±æ¯Transaction 管çConnection ï¼èconnectionä¸ ç¨æ·sessionä¸å¯¹ä¸åå¨ã
å¨springBootä¸ï¼åªéè¦å å ¥POMå°±å¯ä»¥äºï¼é å注解使ç¨å³å¯ã
æ¥ä¸æ¥å°±æ¯äºå¡çæ§å¶äºã
é¦å äºå¡æå å¤§ä¼ æå±æ§ï¼
å ¶ä¸æ常è§çï¼ç¨å¾æå¤å°± PROPAGATION_REQUIREDãPROPAGATION_REQUIRES_NEWã PROPAGATION_NESTED è¿ä¸ç§ãäºå¡çä¼ æå±æ§æ¯ spring ç¹æçï¼æ¯ spring ç¨æ¥æ§å¶æ¹æ³äºå¡çä¸ç§æ段ï¼è¯´ç´ç½ç¹å°±æ¯ç¨æ¥æ§å¶æ¹æ³æ¯å¦ä½¿ç¨åä¸äºå¡çä¸ç§å±æ§ï¼ä»¥åæç §ä»ä¹è§ååæ»çä¸ç§æ段ã
ä¸é¢ç¨ä»£ç æ¼ç¤ºè¿ä¸ç§å±æ§çæºå¶ï¼
äºå¡çé»è®¤å±æ§å°±æ¯requiredï¼éè¿Transactional.javaä¸çPropagation propagation() default Propagation.REQUIRED; å¯ä»¥çåºã
è¿ç§æ åµå°±æ¯äºå¡1ï¼äºå¡2 é½å å ¥å°äºäºå¡0ä¸ãä¸ç®¡æ¯1ï¼2åªä¸ªäºå¡æåºå¼å¸¸ï¼äºå¡0é½ä¼åæ»ãæ°æ®æ·»å ä¼å¤±è´¥ã
è¿ç§æ åµå°±æ¯ï¼
äºå¡0ï¼requiredï¼ {
äºå¡1 ï¼REQUIRES_NEWï¼
äºå¡2
}
æ¤æ¶ã
æ åµaï¼
1ãå¦æåªæ¯äºå¡2åºç°äºå¼å¸¸ï¼é£ä¹äºå¡1ä¼æ交ï¼äºå¡2å å ¥å°äºå¡0ä¸ä¼åæ»ã
2ãå¦æåªæ¯äºå¡1åºç°äºå¼å¸¸ï¼é£ä¹äºå¡1ä¼åæ»ï¼åä¸å±äºå¡0æå¼å¸¸ï¼äºå¡2ä¼å å ¥å°äºå¡0ä¸ï¼è¿æ¶é½ä¼åæ»ã
æ åµbï¼
å¦æäºå¡1ï¼äºå¡2é½æ¯REQUIRES_NEWä¼ æå±æ§ãé£ä¹ç»æå°±æ¯ï¼
1ãå¦æäºå¡1ï¼æåºäºå¼å¸¸ï¼é£ä¹äºå¡2æ¯ä¸ä¼æ§è¡çï¼é£ä¹äºå¡0å¿ ç¶åæ»ã
2ãå¦æäºå¡2ï¼æåºå¼å¸¸ï¼é£ä¹äºå¡1ä¼æ交ï¼è¡¨ä¸ä¼ææ°æ®ãäºå¡2æå¼å¸¸åæ»å¹¶æåºï¼äºå¡0åæ»ã
NESTEDå±æ§å ¶å®å°±æ¯å建äºåæ»ç¹ï¼æå¼å¸¸æ¶ï¼ä¼åæ»å°æå®çåæ»ç¹ã
å¨è¿éè¿ä»£ç æµè¯ï¼åºç°ä¸ç§æ åµæ¯ï¼æ 论äºå¡1ï¼äºå¡2åªä¸ªæå¼å¸¸ï¼æ°æ®é½ä¸ä¼æå ¥æåï¼åå æ¯ï¼ä¸è®ºæ¯äºå¡1è¿æ¯äºå¡2é½ä¼åäºå¡0æåºå¼å¸¸ï¼äºå¡0æè·å°å¼å¸¸åï¼æ§è¡rollback()æ¹æ³ï¼è¿å°±æä½æäºï¼äºå¡çå ¨é¨åæ»ã
å¦ææ³è¦äºå¡1åäºå¡2 æ³è¦æ ¹æ®èªå·±çåæ»ç¹åæ»ï¼é£ä¹äºå¡0å¿ é¡»èªå·±å¤çå¼å¸¸ï¼ä¸è®©springæè·å°è¿ä¸ªå¼å¸¸ï¼é£ä¹å°±æ»¡è¶³äºãæ代ç æ¹æè¿ç§ï¼
Jack大佬æä¾äºï¼ä¼ªä»£ç åææ³ã
æç §Springæºç çäºå¡å¤çé»è¾ï¼ä¼ªä»£ç 大è´ä¸ºï¼
Go能实现AOP吗?
探索 Go 语言是否能实现面向切面编程(AOP)的概念,本文将从 Java 实现 AOP 的码设方式出发,深入讨论 Go 语言的码设特性与 AOP 实现的可能性。Java 中的码设 AOP 通过动态代理和字节码增强技术实现,但在 Go 语言中,码设由于没有虚拟机和中间码的码设汇通区块源码带微盘K线特性,直接源码编译为可执行文件,码设使得代码修改变得困难。码设
然而,码设经过深入研究,码设发现 Go 语言中存在实现类似 AOP 功能的码设库,如 gohook,码设它能够在方法执行前插入逻辑,码设通过反射技术找到方法地址,码设动态地hook方法。码设尽管这种方式实现了一定程度的运行时拦截,但其存在使用限制和未充分测试的问题,不建议在生产环境中使用。
另一种实现 AOP 的sql server课程源码方式是通过抽象语法树(AST)修改源码。Go 语言在编译时会生成 AST 树,可以利用 Go 提供的 API 来生成和操作 AST。通过修改 AST,可以实现 AOP 的功能,例如在方法执行前插入打印语句,或根据注释自动插入代码。尽管这种方式需要在编译期对代码进行生成,但可以提供更灵活的 AOP 实现。
在讨论实现细节的同时,我们也关注到 Go 语言的年轻性与项目阶段。由于 Go 语言相对较新,大多数项目在构建初期,需求通常已在代码中提前设计,减少了对 AOP 这类复杂技术的依赖。不过,随着 Go 社区的发展和项目复杂度的提高,未来出现一个生产可用的 Go AOP 框架并非不可想象。
总结而言,string源码哪里看尽管 Go 语言在实现 AOP 方面面临一定的技术挑战,通过利用运行时拦截和 AST 修改等技术手段,已经能够实现部分 AOP 的功能。但当前 Go 社区对 AOP 的需求相对有限,更多的项目倾向于在设计阶段解决相关需求。随着 Go 应用场景的扩展和项目复杂性的增加,AOP 技术在 Go 语言中的应用可能会逐渐增多。
Spring Boot 使用 AOP 防止重复提交
在Spring Boot项目中,为了简化防止重复提交的处理,可以利用AOP(面向切面编程)实现。传统的做法是后端生成一个唯一令牌并存储,但这样会增加前后端的协作工作。本文将介绍一种无需前端参与的后端处理方式,即使用Redis分布式锁来确保提交的唯一性。 如果你对Redis分布式锁的实现感兴趣,可以参考以下资源:[点击这里了解更多](Redis分布式锁的正确实现方式)。对于单机部署,本地线程安全的虎卫页游源码Cache(如ConcurrentHashMap)同样适用。 下面给出关键的AOP类和测试代码示例:[访问源码](github.com/TavenYin/tav...) 测试案例中,我们模拟十个线程并发提交,结果显示,尽管所有请求几乎同时发起,但只有一次提交成功,充分展示了防止重复提交的效果。要运行这个测试,只需启动本地Redis,然后运行项目即可。更多详细步骤可以参考:[具体步骤](jianshu.com/p/c6bb6...) 如果你还想深入了解相关知识,可以参考以下链接:Web网站架构的发展历程
Java编程的最佳实践
利用Springboot、Redis和注解实现接口幂等性校验
提升Java代码性能的实用技巧
以上是利用Spring Boot和AOP实现防止重复提交的简要介绍,通过分布式锁机制,简化了开发流程,并确保了提交请求的唯一性。
Spring源码插播一个创建代理对象的wrapIfNecessary()方法
在深入探讨Spring源码中创建代理对象的`wrapIfNecessary()`方法之前,先简要回顾其作用。`wrapIfNecessary()`方法主要任务是哎呀买点指标源码基于一系列条件判断,决定是否为Bean创建代理对象,从而实现AOP(面向切面编程)的功能。下面,我们将逐步解析这一方法的内部逻辑。
`wrapIfNecessary()`方法的执行流程可以分为以下阶段:
1. **条件判断**:
- **已处理Bean**:首先检查传入的Bean是否已处理过,即在`targetSourcedBeans`集合中是否存在该Bean的记录。
- **已创建代理**:接着检查`advisedBeans`集合中是否已有该Bean的代理对象缓存,以确认是否需要再次创建代理。
- **自定义Bean**:通过`isInfrastructureClass()`方法判断是否为Spring自带的Bean,排除此类无需代理的情况。
- **无需代理**:如果上述任一条件满足,则直接返回传入的Bean对象,无需创建代理。
2. **代理创建**:
- **获取Advices和Advisors**:如果上述条件均不满足,则调用`getAdvicesAndAdvisorsForBean()`方法获取当前Bean的Advices和Advisors信息。
- **判断适配**:通过`findEligibleAdvisors()`方法从候选通知器中筛选出适合当前Bean的Advisors,确保这些Advisors可以应用到当前Bean。
- **实现逻辑**:通过`findCandidateAdvisors()`和`findAdvisorsThatCanApply()`方法进一步筛选、拓展、排序Advisors,最终获取到实际需要应用的Adviser集合。
3. **代理构建**:
- **决策**:根据获取的Advisors判断是否需要创建代理。若结果非`DO_NOT_PROXY`,则调用`createProxy()`方法创建代理对象,并缓存以备后续使用。
- **过程**:在创建代理过程中,`exposeTargetClass()`方法设置Bean的属性,`shouldProxyTargetClass()`方法决定使用JDK动态代理还是CGLIB动态代理,`evaluateProxyInterfaces()`方法添加代理接口,最终通过`getProxy()`方法构建代理对象。
4. **优化与扩展**:
- **Advisors排序**:调用`sortAdvisors()`方法对Advisors进行排序,优化代理逻辑执行顺序。
- **扩展与定制**:通过`extendAdvisors()`方法提供扩展点,允许对目标Advisor进行进一步定制。
5. **构建代理对象**:
- **代理工厂**:通过`AopProxyFactory`初始化代理工厂,并在构建代理对象时,考虑接口添加、回调函数配置等,最终通过`createProxy()`方法生成可调用的代理对象。
通过这一系列复杂而有序的过程,`wrapIfNecessary()`方法实现了根据特定条件判断是否创建代理对象,并构建出适用于面向切面编程场景的代理对象,进而增强了应用程序的功能性和灵活性。
面试官:你讲讲AOP与OOP有什么区别?
AOP全称为Aspect Oriented Programming,是一种面向切面编程的模式。它与传统的面向对象编程(OOP)有本质的区别。OOP主要关注的是对象的行为和属性,通过封装、继承和多态等特性来实现代码的复用和模块化。而AOP则更侧重于关注点的分离,它可以将一些横跨业务逻辑的公共行为或职责抽取出来,形成独立的模块,从而降低代码的耦合度,提高代码的可维护性和可扩展性。
AOP的核心思想是将业务逻辑中的横切关注点(如日志记录、性能监控、事务管理等)从核心业务代码中分离出来,通过预编译或运行时动态代理的方式进行统一管理和维护。这使得在修改或扩展业务逻辑时,不必修改原有代码,只需要在AOP的配置中添加或修改切点即可。这种分离关注点的设计模式有助于提高开发效率,降低维护成本。
AOP的应用场景通常包括但不限于日志记录、性能统计、安全控制、事务处理、异常处理等。例如,在一个APP模块结构中,按照OOP思想划分的“视图交互”、“业务逻辑”、“网络”等模块,若需要对所有模块的每个方法的执行时间进行监控,这正是AOP的典型应用场景。通过AOP,可以将监控逻辑与业务逻辑分离,无需在每个方法中重复实现监控代码,从而简化了代码结构,提高了代码的可维护性。
AOP的实现方式主要有运行时、加载时和编译时三种,其中编译时实现(如AspectJ)是AOP技术中最常用的一种,它通过在编译阶段将切面代码编织到目标代码中,实现了对目标代码的动态增强。
AspectJ是Java中的AOP实现,它包含两个核心组件:ajc编译器和weaver织入器。ajc编译器用于编译AspectJ的源代码,weaver则在编译或运行时将切面代码编织到目标代码中。在Android项目中使用AspectJ时,可以借助gradle插件来简化配置和集成过程。
总之,AOP提供了一种更为灵活、高效的方式来管理程序中的关注点,与OOP相比,它更加专注于解耦和提高代码的可维护性。在实际开发中,合理运用AOP可以显著提升软件开发的效率和质量。
å¦ä½å®ä¹ä¸ä¸ªaopç»ä»¶
åé¢è¯´è¿äºspringçSchemaæ©å±æ¯æï¼å¯ä»¥çè¿é3.1Springæºç 解æââèªå®ä¹æ ç¾ç使ç¨,è¿éå°±ä¸å¨è¿è¡å¤ä½çå¤è¿°äºãåé¢è®²è¿ï¼Springæ¯æèªå®ä¹çæ©å±ç»ä»¶ï¼ä½æ¯å¿ 须以ä¸ä¸¤ç¹
èªå®ä¹ç±»å¹¶å®ç°SpringçBeanDefinitionParserç±»æ¥è§£æXSDæ件ä¸çå®ä¹åç»ä»¶å®ä¹ï¼
èªå®ä¹ç±»å¹¶å®ç°SpringçNamespaceHandlerSupportç®çæ¯å°ç»å»ºæ³¨åå°Spring容å¨
对åºçæ件ç解æç±»å¯ä»¥å¨META-INFæ件夹çSpring.handlersä¸å¯ä»¥æ¾å°
å¨ä»£ç ä¸å¯¹å®ä¹çAspectç注解è¿è¡è§£æç类为AopNamespaceHandlerï¼
public void init() {// In 2.0 XSD as well as in 2.1 XSD.
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
// Only in 2.0 XSD: moved to context namespace as of 2.1
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}
å¨è§£æé ç½®æ件çæ¶åï¼ä¸æ¦éå°aspectj-autoproxy注解æ¶å°±ä¼ä½¿ç¨è§£æå¨AspectJAutoProxyBeanDefinitionParserè¿è¡è§£æãä¸ä¸ç¯SpringçAOPç解æââAnnotationAwareAspectJAutoProxyCreator
有一本书上有个aop 是什么意思啊
面向方面编程:Aspect Oriented Programming
AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程。可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。
详见
/view/.html?wtp=tt