什么是动态代理
动态代理是指在不修改源代码的情况下,基于运行时生成的静态静态代理类和目标对象之间的代理关系,实现对目标对象方法的代理代理增强处理。以下是源码源码源码起反关于动态代理的详细解释:
一、动态代理的静态静态基本概念
动态代理是一种在运行时生成代理类和目标对象之间代理关系的机制。它不同于静态代理,代理代理静态代理需要在编译时生成具体的源码源码代理类,而动态代理则是静态静态在运行时根据需要生成代理类。这种机制允许开发者在不修改目标对象源代码的代理代理情况下,对目标对象的源码源码方法进行增强处理,例如添加日志、静态静态事务管理、代理代理权限校验等。源码源码
二、动态代理的thinkcmfx源码实现原理
动态代理的实现主要依赖于Java的反射机制。通过反射,代理类可以在运行时获取目标对象的接口、方法和相关属性信息。然后,代理类会在适当的时候调用目标对象的方法,并在调用前后添加自定义的逻辑。这样,就可以实现对目标对象方法的增强处理。
三、动态代理的应用场景
动态代理广泛应用于各种需要方法增强处理的情况。例如,在AOP中,动态代理常被用于实现横切逻辑与目标业务逻辑之间的解耦。此外,在框架和库的设计中,动态代理也常被用于实现一些通用功能,源码汇总如权限校验、缓存处理等。由于动态代理可以在运行时动态生成代理类,因此它具有很高的灵活性和可扩展性。
总之,动态代理是一种强大的技术,它允许开发者在不修改目标对象源代码的情况下,通过运行时生成的代理类实现对目标对象方法的增强处理。这种机制在面向切面编程、框架和库的设计等领域有着广泛的应用。
springå¯å¨åç(springå·¥ç¨å¯å¨)
SpringBootå¯å¨åçåæ
èªå¨é ç½®æ ¸å¿ç±»SpringFactoriesLoader
ä¸é¢å¨è¯´@EnableAutoConfigurationçæ¶åæ说META-INFä¸çspring.factoriesæ件ï¼é£ä¹è¿ä¸ªæ件æ¯æä¹è¢«springå è½½å°çå¢ï¼å ¶å®å°±æ¯SpringFactoriesLoaderç±»ã
SpringFactoriesLoaderæ¯ä¸ä¸ªä¾Springå é¨ä½¿ç¨çéç¨å·¥åè£ è½½å¨å®éï¼SpringFactoriesLoaderéæ两个æ¹æ³ï¼
å¨è¿ä¸ªSpringBootåºç¨å¯å¨è¿ç¨ä¸ï¼SpringFactoriesLoaderåäºä»¥ä¸å 件äºï¼
å è½½ææMETA-INF/spring.factoriesä¸çInitializer
å è½½ææMETA-INF/spring.factoriesä¸çListener
å è½½EnvironmentPostProcessorï¼å 许å¨Springåºç¨æ建ä¹åå®å¶ç¯å¢é ç½®ï¼
æ¥ä¸æ¥å è½½PropertiesåYAMLçPropertySourceLoaderï¼é对SpringBootç两ç§é ç½®æ件çå è½½å¨ï¼
åç§å¼å¸¸æ åµçFailureAnalyzerï¼å¼å¸¸è§£éå¨ï¼
å è½½SpringBootå é¨å®ç°çåç§AutoConfiguration
模æ¿å¼æTemplateAvailabilityProviderï¼å¦FreemarkerãThymeleafãJspãVelocityçï¼
æ»å¾æ¥è¯´ï¼SpringFactoriesLoaderå@EnableAutoConfigurationé åèµ·æ¥ï¼æ´ä½åè½å°±æ¯æ¥æ¾spring.factoriesæ件ï¼å è½½èªå¨é 置类ã
æ´ä½å¯å¨æµç¨
å¨æ们æ§è¡å ¥å£ç±»çmainæ¹æ³ä¹åï¼è¿è¡SpringApplication.runï¼åé¢newäºä¸ä¸ªSpringApplication对象ï¼ç¶åæ§è¡å®çrunæ¹æ³ã
åå§åSpringApplicationç±»
å建ä¸ä¸ªSpringApplication对象æ¶ï¼ä¼è°ç¨å®èªå·±çinitializeæ¹æ³
æ§è¡æ ¸å¿runæ¹æ³
åå§åinitializeæ¹æ³æ§è¡å®ä¹åï¼ä¼è°ç¨runæ¹æ³ï¼å¼å§å¯å¨SpringBootã
é¦å éåæ§è¡ææéè¿SpringFactoriesLoaderï¼å¨å½åclasspathä¸çMETA-INF/spring.factoriesä¸æ¥æ¾ææå¯ç¨çSpringApplicationRunListeners并å®ä¾åãè°ç¨å®ä»¬çstarting()æ¹æ³ï¼æ¶²è½éç¥è¿äºçå¬å¨SpringBootåºç¨å¯å¨ã
å建并é ç½®å½åSpringBootåºç¨å°è¦ä½¿ç¨çEnvironmentï¼å æ¬å½åææçPropertySource以åProfileã
éåè°ç¨ææçSpringApplicationRunListenersçenvironmentPrepared()çæ¹æ³ï¼éç¥è¿äºçå¬å¨SpringBootåºç¨çEnvironmentå·²ç»å®æåå§åã
æå°SpringBootåºç¨çbannerï¼SpringApplicationçshowBannerå±æ§ä¸ºtrueæ¶ï¼å¦æclasspathä¸åå¨banner.txtæ件ï¼åæå°å ¶å 容ï¼å¦åæå°é»è®¤bannerã
æ ¹æ®å¯å¨æ¶è®¾ç½®çapplicationContextClassåå¨initializeæ¹æ³è®¾ç½®çwebEnvironmentï¼å建对åºçapplicationContextã
å建å¼å¸¸è§£æå¨ï¼ç¨å¨å¯å¨ä¸åçå¼å¸¸çæ¶åè¿è¡å¼å¸¸å¤ç(å æ¬è®°å½æ¥å¿ãéæ¾èµæºç)ã
设置SpringBootçEnvironmentï¼æ³¨åSpringBeanå称çåºååå¨BeanNameGeneratorï¼å¹¶è®¾ç½®èµæºå è½½å¨ResourceLoaderï¼éè¿SpringFactoriesLoaderå è½½ApplicationContextInitializeråå§åå¨ï¼è°ç¨initializeæ¹æ³ï¼å¯¹å建çApplicationContextè¿ä¸æ¥åå§åã
è°ç¨ææçSpringApplicationRunListenersçcontextPreparedæ¹æ³ï¼éç¥é¹ç»å·è¿äºListenerå½åApplicationContextå·²ç»å建å®æ¯ã
ææ ¸å¿çä¸æ¥ï¼å°ä¹åéè¿@EnableAutoConfigurationè·åçææé 置以åå ¶ä»å½¢å¼çIoC容å¨é ç½®å è½½å°å·²ç»åå¤å®æ¯çApplicationContextã
è°ç¨ææçSpringApplicationRunListenerçcontextLoadedæ¹æ³ï¼å è½½åå¤å®æ¯çApplicationContextã
è°ç¨refreshContextï¼æ³¨åä¸ä¸ªå ³éSpring容å¨çé©åShutdownHookï¼å½ç¨åºå¨åæ¢çæ¶åéæ¾èµæºï¼å æ¬ï¼éæ¯Beanï¼å ³éSpringBeançå建工åçï¼
注ï¼é©åå¯ä»¥å¨ä»¥ä¸å ç§åºæ¯ä¸è¢«è°ç¨ï¼
1ï¼ç¨åºæ£å¸¸éåº
2ï¼ä½¿ç¨System.exit()
3ï¼ç»ç«¯ä½¿ç¨Ctrl+C触åçä¸æ
4ï¼ç³»ç»å ³é
5ï¼ä½¿ç¨Killpidå½ä»¤ææ»è¿ç¨
è·åå½åææApplicationRunneråCommandLineRunneræ¥å£çå®ç°ç±»ï¼æ§è¡å ¶runæ¹æ³
éåææçSpringApplicationRunListenerçfinished()æ¹æ³ï¼å®æSpringBootçå¯å¨ã
springå·¥ä½åç
Springçå·¥ä½åçæ¯è®©ä¸ä¸ªå¯¹è±¡çå建ä¸ç¨newå°±å¯ä»¥èªå¨çç产ï¼å¨è¿è¡æ¶ä¸xmlSpringçé ç½®æ件æ¥é«å²©å¨æçå建对象åè°ç¨å¯¹è±¡ï¼èä¸éè¦éè¿ä»£ç æ¥å ³èã
Springæ¯ä¸ä¸ªå¼æ¾æºä»£ç ç设计å±é¢æ¡æ¶ï¼ä»è§£å³çæ¯ä¸å¡é»è¾å±åå ¶ä»åå±çæ¾è¦åé®é¢ï¼å æ¤å®å°é¢åæ¥å£çç¼ç¨ææ³è´¯ç©¿æ´ä¸ªç³»ç»åºç¨ã
springç¹ç¹æ¯1.æ¹ä¾¿è§£è¦ï¼ç®åå¼åã2.AOPç¼ç¨çæ¯æã3.声æå¼äºå¡çæ¯æã4.æ¹ä¾¿ç¨åºçæµè¯ã5.æ¹ä¾¿éæåç§ä¼ç§æ¡æ¶ã6.éä½JavaEEAPIç使ç¨é¾åº¦ã7.Javaæºç æ¯ç»å ¸å¦ä¹ èä¾ã
Springæ¡æ¶æ¯ç±äºè½¯ä»¶å¼åçå¤ææ§èå建çãSpring使ç¨çæ¯åºæ¬çJavaBeanæ¥å®æ以ååªå¯è½ç±EJBå®æçäºæ ãç¶èï¼Springçç¨éä¸ä» ä» éäºæå¡å¨ç«¯çå¼åãä»ç®åæ§ãå¯æµè¯æ§åæ¾è¦åæ§è§åº¦èè¨ï¼ç»å¤§é¨åJavaåºç¨é½å¯ä»¥ä»Springä¸å¸¦æ¶åçãSpringæ¯ä¸ä¸ªè½»é级çæ§å¶å转(IoC)åé¢ååé¢(AOP)ç容å¨æ¡æ¶ã
Springéè¿ä¸ç§ç§°ä½æ§å¶å转ï¼IoCï¼çææ¯ä¿è¿äºæ¾è¦åãå½åºç¨äºIoCï¼ä¸ä¸ªå¯¹è±¡ä¾èµçå ¶å®å¯¹è±¡ä¼éè¿è¢«å¨çæ¹å¼ä¼ éè¿æ¥ï¼èä¸æ¯è¿ä¸ªå¯¹è±¡èªå·±å建æè æ¥æ¾ä¾èµå¯¹è±¡ãä½ å¯ä»¥è®¤ä¸ºIoCä¸JNDIç¸åââä¸æ¯å¯¹è±¡ä»å®¹å¨ä¸æ¥æ¾ä¾èµï¼èæ¯å®¹å¨å¨å¯¹è±¡åæè¡å¾¡å§åæ¶ä¸ç对象请æ±å°±ä¸»å¨å°ä¾èµä¼ éç»å®ã
springçåçæ¯ä»ä¹ï¼ä¸ãIoC(Inversionofcontrol):æ§å¶å转\x0d\1ãIoCï¼\x0d\æ¦å¿µï¼æ§å¶æç±å¯¹è±¡æ¬èº«è½¬å容å¨ï¼ç±å®¹å¨æ ¹æ®é ç½®è ¢è¡«æ件å»å建å®ä¾å¹¶å建å个å®ä¾ä¹é´çä¾èµå ³ç³»\x0d\æ ¸å¿ï¼beanå·¥åï¼å¨Springä¸ï¼beanå·¥åå建çå个å®ä¾ç§°ä½bean\x0d\äºãAOP(Aspect-OrientedProgramming):é¢åæ¹é¢ç¼ç¨ã\x0d\1ã代çç两ç§æ¹å¼ï¼\x0d\éæ代çï¼\x0d\é对æ¯ä¸ªå ·ä½ç±»åå«ç¼å代çç±»ã\x0d\é对ä¸ä¸ªæ¥å£ç¼åä¸ä¸ªä»£çç±»ã\x0d\å¨æ代çï¼\x0d\é对ä¸ä¸ªæ¹é¢ç¼åä¸ä¸ªInvocationHandlerï¼ç¶ååç¨JDKåå°å ä¸çProxy类为åç§æ¥å£å¨æçæç¸åºç代çç±»ã\x0d\2ãAOPç主è¦åçï¼å¨æ代çã\x0d\Springå·¥ä½åç\x0d\Springå·²ç»ç¨è¿ä¸æ®µæ¶é´äºï¼æè§Springæ¯ä¸ªå¾ä¸éçæ¡æ¶ãå é¨ææ ¸å¿çå°±æ¯IOCäºï¼\x0d\å¨ææ³¨å ¥ï¼è®©ä¸ä¸ªå¯¹è±¡çå建ä¸ç¨newäºï¼å¯ä»¥èªå¨çç产ï¼è¿å ¶å®å°±æ¯å©ç¨javaéçåå°ï¼åå°å ¶å®å°±æ¯å¨è¿è¡æ¶å¨æçå»å建ãè°ç¨å¯¹è±¡ï¼Springå°±æ¯å¨è¿è¡æ¶ï¼è·xmlSpringçé ç½®æ件æ¥å¨æçå建对象ï¼åè°ç¨å¯¹è±¡éçæ¹æ³çã\x0d\Springè¿æä¸ä¸ªæ ¸å¿å°±æ¯AOPè¿ä¸ªå°±æ¯é¢ååé¢ç¼ç¨ï¼å¯ä»¥ä¸ºæä¸ç±»å¯¹è±¡è¿è¡çç£åæ§å¶ï¼ä¹å°±æ¯å¨è°ç¨è¿ç±»å¯¹è±¡çå ·ä½æ¹æ³çååå»è°ç¨ä½ æå®ç模åï¼ä»èè¾¾å°å¯¹ä¸ä¸ªæ¨¡åæ©å çåè½ãè¿äºé½æ¯éè¿é 置类达å°è°åºçã\x0d\Springç®çå«æ¡£æ¡ï¼å°±æ¯è®©å¯¹è±¡ä¸å¯¹è±¡ï¼æ¨¡åä¸æ¨¡åï¼ä¹é´çå ³ç³»æ²¡æéè¿ä»£ç æ¥å ³èï¼é½æ¯éè¿é 置类说æ管ççï¼Springæ ¹æ®è¿äºé ç½®å é¨éè¿åå°å»å¨æçç»è£ 对象ï¼\x0d\è¦è®°ä½ï¼Springæ¯ä¸ä¸ªå®¹å¨ï¼å¡æ¯å¨å®¹å¨éç对象æä¼æSpringææä¾çè¿äºæå¡ååè½ã\x0d\Springéç¨çæç»å ¸çä¸ä¸ªè®¾è®¡æ¨¡å¼å°±æ¯ï¼æ¨¡æ¿æ¹æ³æ¨¡å¼ã
SpringBootåºç¨å¯å¨åç(äº)æ©å±URLClassLoaderå®ç°åµå¥jarå è½½å¨ä¸ç¯æç« ãSpringBootåºç¨å¯å¨åç(ä¸)å°å¯å¨èæ¬åµå ¥jarãä¸ä»ç»äºSpringBootå¦ä½å°å¯å¨èæ¬ä¸RunnableJaræ´å为ExecutableJarçåçï¼ä½¿å¾çæçjar/waræ件å¯ä»¥ç´æ¥å¯å¨
æ¬ç¯å°ä»ç»SpringBootå¦ä½æ©å±URLClassLoaderå®ç°åµå¥jarçç±»(èµæº)å è½½ï¼ä»¥å¯å¨æ们çåºåæ£æç¨ã
é¦å 岩ä¼ï¼ä»ä¸ä¸ªç®åç示ä¾å¼å§
build.gradle
WebApp.java
æ§è¡gradlebuildæ建jarå ï¼éé¢å å«åºç¨ç¨åºã第ä¸æ¹ä¾èµä»¥åSpringBootå¯å¨ç¨åºï¼å ¶ç®å½ç»æå¦ä¸
æ¥çMANIFEST.MFçå 容(MANIFEST.MFæ件çä½ç¨è¯·èªè¡GOOGLE)
å¯ä»¥çå°ï¼jarçå¯å¨ç±»ä¸ºorg.springframework.boot.loader.JarLauncherï¼è并ä¸æ¯æ们çcom.manerfan.SpringBoot.theory.WebAppï¼åºç¨ç¨åºå ¥å£ç±»è¢«æ 记为äºStart-Class
jarå¯å¨å¹¶ä¸æ¯éè¿åºç¨ç¨åºå ¥å£ç±»ï¼èæ¯éè¿JarLauncher代çå¯å¨ãå ¶å®SpringBootæ¥æ3ä¸ä¸åçLauncherï¼JarLauncherãWarLauncherãPropertiesLauncher
SpringBoot使ç¨Launcher代çå¯å¨ï¼å ¶æéè¦çä¸ç¹ä¾¿æ¯å¯ä»¥èªå®ä¹ClassLoaderï¼ä»¥å®ç°å¯¹jaræ件å ï¼jarinjarï¼æå ¶ä»è·¯å¾ä¸jarãclassæèµæºæ件çå è½½
å ³äºClassLoaderçæ´å¤ä»ç»å¯åèãæ·±å ¥ç解JVMä¹ClassLoaderã
SpringBootæ½è±¡äºArchiveçæ¦å¿µï¼ä¸ä¸ªArchiveå¯ä»¥æ¯jarï¼JarFileArchiveï¼ï¼å¯ä»¥æ¯ä¸ä¸ªæ件ç®å½ï¼ExplodedArchiveï¼ï¼å¯ä»¥æ½è±¡ä¸ºç»ä¸è®¿é®èµæºçé»è¾å±ã
ä¸ä¾ä¸ï¼spring-boot-theory-1.0.0.jaræ¢ä¸ºä¸ä¸ªJarFileArchiveï¼spring-boot-theory-1.0.0.jar!/BOOT-INF/libä¸çæ¯ä¸ä¸ªjarå ä¹æ¯ä¸ä¸ªJarFileArchive
å°spring-boot-theory-1.0.0.jar解åå°ç®å½spring-boot-theory-1.0.0ï¼åç®å½spring-boot-theory-1.0.0为ä¸ä¸ªExplodedArchive
æç §å®ä¹ï¼JarLauncherå¯ä»¥å è½½å é¨/BOOT-INF/libä¸çjarå/BOOT-INF/classesä¸çåºç¨class
å ¶å®JarLauncherå®ç°å¾ç®å
å ¶ä¸»å ¥å£æ°å»ºäºJarLauncher并è°ç¨ç¶ç±»Launcherä¸çlaunchæ¹æ³å¯å¨ç¨åº
åå建JarLauncheræ¶ï¼ç¶ç±»ExecutableArchiveLauncheræ¾å°èªå·±æå¨çjarï¼å¹¶å建archive
å¨Launcherçlaunchæ¹æ³ä¸ï¼éè¿ä»¥ä¸archiveçgetNestedArchivesæ¹æ³æ¾å°/BOOT-INF/libä¸ææjarå/BOOT-INF/classesç®å½æ对åºçarchiveï¼éè¿è¿äºarchivesçurlçæLaunchedURLClassLoaderï¼å¹¶å°å ¶è®¾ç½®ä¸ºçº¿ç¨å¥½æ©¡ä¸ä¸æç±»å è½½å¨ï¼å¯å¨åºç¨
è³æ¤ï¼ææ§è¡æ们åºç¨ç¨åºä¸»å ¥å£ç±»çmainæ¹æ³ï¼ææåºç¨ç¨åºç±»æ件åå¯éè¿/BOOT-INF/classeså è½½ï¼ææä¾èµç第ä¸æ¹jaråå¯éè¿/BOOT-INF/libå è½½
å¨åæLaunchedURLClassLoaderåï¼é¦å äºè§£ä¸ä¸URLStreamHandler
javaä¸å®ä¹äºURLçæ¦å¿µï¼å¹¶å®ç°å¤ç§URLåè®®ï¼è§URLï¼*http**file**ftp**jar*çï¼ç»å对åºçURLConnectionå¯ä»¥çµæ´»å°è·ååç§åè®®ä¸çèµæº
对äºjarï¼æ¯ä¸ªjaré½ä¼å¯¹åºä¸ä¸ªurlï¼å¦
jar:file:/data/spring-boot-theory/BOOT-INF/lib/spring-aop-5.0.4.RELEASE.jar!/
jarä¸çèµæºï¼ä¹ä¼å¯¹åºä¸ä¸ªurlï¼å¹¶ä»¥'!/'åå²ï¼å¦
jar:file:/data/spring-boot-theory/BOOT-INF/lib/spring-aop-5.0.4.RELEASE.jar!/org/springframework/aop/SpringProxy.class
对äºåå§çJarFileURLï¼åªæ¯æä¸ä¸ª'!/'ï¼SpringBootæ©å±äºæ¤åè®®ï¼ä½¿å ¶æ¯æå¤ä¸ª'!/'ï¼ä»¥å®ç°jarinjarçèµæºï¼å¦
jar:file:/data/spring-boot-theory.jar!/BOOT-INF/lib/spring-aop-5.0.4.RELEASE.jar!/org/springframework/aop/SpringProxy.class
èªå®ä¹URLçç±»æ ¼å¼ä¸º[pkgs].[protocol].Handlerï¼å¨è¿è¡Launcherçlaunchæ¹æ³æ¶è°ç¨äºJarFile.registerUrlProtocolHandler()以注åèªå®ä¹çHandler
å¨å¤çå¦ä¸URLæ¶ï¼ä¼å¾ªç¯å¤ç'!/'åé符ï¼ä»æä¸å±åºåï¼å æé spring-boot-theory.jarçJarFileï¼åæé spring-aop-5.0.4.RELEASE.jarçJarFileï¼æåæé æåSpringProxy.classç
JarURLConnectionï¼éè¿JarURLConnectionçgetInputStreamæ¹æ³è·åSpringProxy.classå 容
ä»ä¸ä¸ªURLï¼å°è¯»åå ¶ä¸çå 容ï¼æ´ä¸ªè¿ç¨ä¸º
URLClassLoaderå¯ä»¥éè¿åå§çjaråè®®ï¼å è½½jarä¸ä»classæ件
LaunchedURLClassLoaderéè¿æ©å±çjaråè®®ï¼ä»¥å®ç°jarinjarè¿ç§æ åµä¸çclassæ件å è½½
æ建warå å¾ç®å
æ建åºçwarå ï¼å ¶ç®å½æºæ为
MANIFEST.MFå 容为
æ¤æ¶ï¼å¯å¨ç±»å为äºorg.springframework.boot.loader.WarLauncherï¼æ¥çWarLauncherå®ç°ï¼å ¶å®ä¸JarLauncher并æ 太大差å«
å·®å«ä» å¨äºï¼JarLauncherå¨æ建LauncherURLClassLoaderæ¶ï¼ä¼æç´¢BOOT-INF/classesç®å½åBOOT-INF/libç®å½ä¸jarï¼WarLauncherå¨æ建LauncherURLClassLoaderæ¶ï¼åä¼æç´¢WEB-INFO/classesç®å½åWEB-INFO/libåWEB-INFO/lib-provided两个ç®å½ä¸çjar
å¦æ¤ä¾èµï¼æ建åºçwar便æ¯æ两ç§å¯å¨æ¹å¼
PropretiesLauncherçå®ç°ä¸JarLauncherWarLauncherçå®ç°æ为ç¸ä¼¼ï¼éè¿PropretiesLauncherå¯ä»¥å®ç°æ´ä¸ºè½»éçthinjarï¼å ¶å®ç°æ¹å¼å¯èªè¡æ¥é æºç
SpringBootè¿è¡åçSpringBootæ¯ä¸ä¸ªåºäºSpringå¼åï¼éæäºå¤§é第ä¸æ¹åºé ç½®çjavawebå¼åæ¡æ¶
pom.xml
ç¶ä¾èµ
å ¶ä¸å®ä¸»è¦æ¯ä¾èµä¸ä¸ªç¶é¡¹ç®ï¼ä¸»è¦æ¯ç®¡ç项ç®çèµæºè¿æ»¤åæ件ã以åæä»¬å¯¼å ¥ä¾èµé»è®¤æ¯ä¸éè¦åçæ¬çã
å¯å¨å¨spring-boot-starter
springboot-boot-starter-xxx:spring-bootçåºæ¯å¯å¨å¨é御
spring-boot-starter-web:帮æä»¬å¯¼å ¥äºweb模åæ£å¸¸è¿è¡æä¾èµçç»ä»¶ã
springBootå°ææçåè½åºæ¯é½æ½ååºæ¥ï¼åæä¸ä¸ªä¸ªçstarter(å¯å¨å¨)ï¼åªéè¦å¨é¡¹ç®ä¸å¼å ¥è¿äºstarterå³å¯ï¼ææç¸å ³çä¾èµé½ä¼è¢«å¼è¿æ¥ï¼æ们è¦ç¨ä»ä¹åè½å°±å¯¼å ¥ä»ä¹æ ·çåºæ¯å¯å¨å¨å³å¯ã
@SpringBootApplication
ä½ç¨ï¼æ 注å¨æ个类ä¸è¯´æè¿ä¸ªç±»æ¯SpringBootç主é 置类ï¼SpringBootè¿è¡è¿ä¸ªç±»çmainæ¹æ³æ¥å¯å¨SpringBootåºç¨ã
è¿å ¥è¿ä¸ªæ³¨è§£ï¼éé¢å å«äºå¾å¤å ¶ä»æ³¨è§£
@ComponentScanä½ç¨ï¼èªå¨æ«æ并å 载符åæ¡ä»¶çç»ä»¶æè beanï¼å°è¿ä¸ªbeanå®ä¹å è½½å°IOC容å¨ä¸ã
@SpringBootConfigurationä½ç¨ï¼SpringBootçé 置类ï¼æ 注å¨æ个类ä¸ï¼è¡¨ç¤ºè¿æ¯ä¸ä¸ªå§¿åSpringBootçé 置类ã
è¿å ¥@SpringBootConfiguration注解æ¥çï¼è¿éç@Configuration说æè¿æ¯ä¸ä¸ªé 置类ï¼é 置类对åºSpringçxmlé ç½®æ件ã
继ç»æ¥ç@SpringBootConfigurationå å«çå ¶ä»æ³¨è§£
@EnableAutoConfigurationï¼å¼å¯èªå¨é ç½®åè½
è¿å ¥@EnableAutoConfiguration注解æ¥ç
@AutoConfigurationPackageèªå¨é ç½®å
@importï¼Springåºå±æ³¨è§£@importï¼ç»å®¹å¨ä¸å¯¼å ¥ä¸ä¸ªç»ä»¶
@Importï¼{ AutoConfigurationImportSelector.class}ï¼ç»å®¹å¨å¯¼å ¥ç»ä»¶
AutoConfigurationImportSelectorï¼èªå¨é ç½®å¯¼å ¥éæ©å¨ãé£ä¹å®å¯¼å ¥åªäºç»ä»¶çéæ©å¨å¢
è¿ä¸ªç±»ä¸æè¿æ ·ä¸ä¸ªæ¹æ³ï¼getCandidateConfiguration,èå¨è¿ä¸ªæ¹æ³ä¸æè°ç¨äºSpringFactoriesLoaderç±»çéææ¹æ³loadFactoryNames()æ¹æ³
è¿å ¥loadSpringFactoriesæ¹æ³
æ ¹æ®å ¨å±æç´¢Spring.factoriesï¼æå¼åæ¯èªå¨é ç½®çæ件ã
é便æå¼ä¸ä¸ªå ¶ä¸çèªå¨é 置类çï¼å®ä»¬é½åå岩æ¯javaConfigé 置类ï¼é½æ³¨å ¥äºä¸äºBean
æ以ï¼èªå¨é ç½®çæ£å®ç°æ¯ä»classpathä¸æ寻ææçMETA-INF/spring.factoriesé ç½®æ件ï¼å¹¶å°å ¶ä¸å¯¹åºçorg.springframework.boot.autoconfigureå ä¸çé 置项éè¿åå°å®ä¾å为对åºæ 注äº@ConfigurationçjavaConfigå½¢å¼çIOC容å¨é 置类ï¼ç¶åå°è¿äºé½æ±æ»æ为ä¸ä¸ªå®ä¾å¹¶å è½½å°IOC容å¨ä¸ã
ç»è®ºï¼
1.SpringBootå¨å¯å¨çæ¶åä»ç±»è·¯å¾ä¸çMETA-INF/spring.factoriesä¸è·åEnableAutoConfigurationæå®çå¼
2.å°è¿äºå¼ä½ä¸ºèªå¨é ç½®ç±»å¯¼å ¥å®¹å¨ï¼èªå¨é 置类就çæï¼å¸®æ们è¿è¡èªå¨é 置工ä½ã
3.æ´ä¸ªJ2EEçæ´ä½è§£å³æ¹æ¡åèªå¨é ç½®é½å¨springboot-autoConfigureçjarå ä¸ã
4.å®ä¼ç»å®¹å¨ä¸å¯¼å ¥é常å¤çèªå¨é 置类ï¼xxxAutoConfigurationï¼,å°±æ¯ç»å®¹å¨ä¸å¯¼å ¥è¿ä¸ªåºæ¯éè¦çææç»ä»¶ï¼å¹¶é 置好è¿äºç»ä»¶ã
5.æäºèªå¨é 置类ï¼å å»äºæ们æå¨ç¼åé ç½®æ³¨å ¥åè½ç»ä»¶ççå·¥ä½ã
SpringApplication
è¿ä¸ªç±»ä¸»è¦åäºä»¥ä¸å件äº
1.æ¨æåºç¨çç±»åæ¯æ®éç项ç®è¿æ¯web项ç®
2.æ¥æ¾å¹¶å è½½ææå¯ç¨åå§åå¨ï¼è®¾ç½®å°initializerså±æ§ä¸
3.æ¾åºææçåºç¨ç¨åºçå¬å¨ï¼è®¾ç½®å°listenerså±æ§ä¸
4.æ¨æ并设置mainæ¹æ³çå®ä¹ç±»ï¼æ¾å°è¿è¡ç主类
SpringbootBatchçå¯å¨åç-ConfigurationSpringbootæ´åäºwebåbatchï¼ä½æ¯ä»ä»¬è¯å®ä¸æ¯åä¸æ¡è·¯ï¼å¨springbootä¸ï¼ä¼æ¨æå½åçè¿è¡ç¯å¢ãthis.webApplicationType=WebApplicationType.deduceFromClasspath();
ä»ä¸ç¨¿æ¨±æå¯ä»¥çåºï¼Springå°è¯ä»classpathéæ¾å°ç¹å¾ç±»ï¼æ¥å¤æå½åappæ¯ä»ä¹ç±»åãå½ç¶è¿ç§å¤ææ¯æå±éæ§çï¼æå¯è½æ¯transitive带ææ¸è¿æ¥ä¸ä¸ªå¸¦æservletç类被å½æäºWebApplicationType.SERVLETï¼å®é ä¸æ¯ä¸ªWebApplicationType.NONE;ãå¦æä¸æ³ä»¥webè¿è¡å°±æ¯æ³è¿è¡batchå¯ä»¥å¨application.properties强è¡æå®WebApplicationType
å ·ä½åçä½ç¨ç请çä¸é¢çstacktrace
å½ä¸ä¸ªbatchapplicationéè¦å¯å¨ï¼éè¦é ç½®JobRepositoryï¼Datasourceççï¼ææçå¼å§é½æ¥èªä¸ä¸ªannotation@EnableBatchProcessing
å½å å ¥@EnableBatchProcessingæ¶ï¼BatchConfigurationSelectorå¼å§å¯å¨ï¼æä¹å¯å¨ç大家å¯ä»¥é®æä¸åèä¸é¢çstacktraceã
import类主è¦æ¯ç±ConfigurationClassPostProcessoræ¥å®ç°çãå½BatchConfigurationSelector被è°ç¨çæ¶åï¼æ们å¯ä»¥çå°ä»æ两æ¡æ¯è·¯ã
é£ä¹è¿ä¸¤æ¡è·¯æå¥ä¸åå¢ã主è¦æ¯jobå®ä¹çæ¹å¼ä¸åã
modular=trueçæ åµä¸ï¼ä¸é¢æ¯ä¸ä¸ªä¾å
å¯ä»¥æå¤ä¸ªåAp
代理模式与静态代理、动态代理的实现(Proxy.newProxyInstance、InvocationHandler)
代理模式在设计模式中被广泛应用,尤其是在Android开发中,如Retrofit利用动态代理实现API接口调用,Dagger使用代码生成和反射机制创建依赖注入代理。vmprotect 源码本文将详细解释代理模式,并探讨静态代理与动态代理的实现方式。
代理模式的核心思想在于不直接访问目标对象,而是通过访问代理对象来间接操作目标。例如,与明星打交道时,通过经纪人(代理)进行联系而非直接接触明星。这种方式能实现目标对象功能的扩展,增强额外操作。
代理模式实现有静态代理与动态代理。静态代理中代理与目标对象共用接口或继承同一父类。操作流程如下:定义接口或父类、目标对象类、代理对象类、使用代理类。静态代理易于理解,mockito源码但存在代码冗余和扩展性差的缺点。
动态代理是通过运行时生成代理对象实现的,无需代理与目标对象共用接口。Java中Proxy类提供方法生成代理对象。动态代理在内存中构建代理类,允许在运行时为目标对象添加功能,而无需修改源代码。实现过程包括确定目标接口、目标对象、调用newProxyInstance生成代理对象、使用代理对象。
动态代理实现了灵活性与扩展性,是实际开发中更常用的代理模式。但代理对象仍需目标对象实现接口。对于未实现接口的目标对象,可使用cglib或ByteBuddy库进行代理。
cglib库虽能实现非接口目标对象的代理,但已不再维护,新版本Java中可能存在兼容性问题。因此,推荐使用ByteBuddy库。ByteBuddy库在代理非接口目标对象方面提供了更稳定、高效的解决方案。
总结,代理模式提供了一种在不修改目标对象代码的情况下扩展其功能的方法。静态代理简洁直观,但存在扩展性限制;动态代理则在运行时实现代理,提供更多灵活性,但需目标对象实现接口。对于未实现接口的目标对象,可借助cglib或ByteBuddy库实现代理。选择合适的代理模式及库能够有效提升系统设计与实现的灵活性与效率。
UE4 代理(Delegate)源码浅析(3)
本文章仅为个人在学习虚幻引擎过程中的理解,可能存在不准确之处,如有错误,欢迎指正。
本文将深入探讨虚幻引擎中的两种动态代理机制,并与静态代理进行比较。前两篇已详细介绍了静态代理和事件机制,本篇作为系列的终结篇,将重点解析动态代理。
动态代理与静态代理的主要区别在于动态代理能够与蓝图进行交互。本文将通过分析源码,揭示动态代理实现与静态代理的区别。
动态单播代理的实现基于宏DECLARE_DYNAMIC_DELEGATE_OneParam。宏接收三个参数:代理名、参数类型和参数名。宏使用BODY_MACRO_COMBINE辅助宏,将参数拼接为独一无二的名字,进而实现代理类的封装。
执行代理方法通常涉及宏FUNC_DECLARE_DYNAMIC_DELEGATE,该宏接收多个参数,如弱指针类型、代理名、执行函数接口、参数类型列表、真正传给绑定函数的参数等。这些参数在执行函数接口中整合,实现动态代理的执行。
动态单播代理的父类TBaseDynamicDelegate内部定义了TMethodPtrResolver,用于处理代理的绑定。__Internal_BindDynamic方法实现代理绑定功能。动态单播代理继承自TScriptDelegate,该类提供了与代理绑定相关的各种方法。
动态多播代理的实现方式与静态多播相似,内部保存动态单播的数组,用于执行代理时调用数组中绑定的函数,实现多播效果。动态多播代理的宏为DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam,其内部实现与动态单播代理类似。
动态多播代理的父类TBaseDynamicMulticastDelegate提供了代理绑定的内部接口,如判断代理是否绑定、添加绑定、删除绑定等。动态多播代理继承自TMulticastScriptDelegate,该类定义了用于处理多播代理的数组实例。
总结而言,动态代理与静态代理的架构类似,通过不同的参数配置和宏实现,实现了与蓝图的交互。动态代理在实现上更加灵活,支持多播和单播功能,为虚幻引擎提供了强大的事件处理能力。本文旨在提供动态代理的源码解析,帮助开发者更好地理解和使用虚幻引擎的代理机制。
springaopåç
åçï¼sping aopæ¯å¯ä»¥éè¿é¢ç¼è¯æ¹å¼åè¿è¡æå¨æ代çå®ç°å¨ä¸ä¿®æ¹æºä»£ç çæ åµä¸ç»ç¨åºå¨æç»ä¸æ·»å åè½çä¸ç§ææ¯ãAOP设计模å¼ååä¸å¦è¿½æ±çæ¯è°ç¨è å被è°ç¨è ä¹é´ç解è¦ï¼AOP å¯ä»¥è¯´ä¹æ¯è¿ç§ç®æ çä¸ç§å®ç°ãå ¶åççç¸å ³ææ¯ï¼
AOPæ¯OOPç延ç»ï¼æ¯Aspect Oriented Programmingç缩åï¼æææ¯é¢ååé¢ç¼ç¨ãAOPï¼è¿éçAOPæçæ¯é¢ååé¢ç¼ç¨ææ³ï¼èä¸æ¯Spring AOPï¼ä¸»è¦ççå®ç°ææ¯ä¸»è¦æSpring AOPåAspectJã
AspectJçåºå±ææ¯æ¯éæ代çï¼å³ç¨ä¸ç§AspectJæ¯æçç¹å®è¯è¨ç¼ååé¢ï¼éè¿ä¸ä¸ªå½ä»¤æ¥ç¼è¯ï¼çæä¸ä¸ªæ°ç代çç±»ï¼è¯¥ä»£çç±»å¢å¼ºäºä¸å¡ç±»ï¼è¿æ¯å¨ç¼è¯æ¶å¢å¼ºï¼ç¸å¯¹äºä¸é¢è¯´çè¿è¡æ¶å¢å¼ºï¼ç¼è¯æ¶å¢å¼ºçæ§è½æ´å¥½ã
Spring AOPéç¨çæ¯å¨æ代çï¼å¨è¿è¡æé´å¯¹ä¸å¡æ¹æ³è¿è¡å¢å¼ºï¼æ以ä¸ä¼çææ°ç±»ï¼å¯¹äºå¨æ代çææ¯ï¼Spring AOPæä¾äºå¯¹JDKå¨æ代ççæ¯æ以åCGLibçæ¯æã
JDKå¨æ代çåªè½ä¸ºæ¥å£å建å¨æ代çå®ä¾ï¼èä¸è½å¯¹ç±»å建å¨æ代çãéè¦è·å¾è¢«ç®æ ç±»çæ¥å£ä¿¡æ¯ï¼åºç¨Javaçåå°ææ¯ï¼ï¼çæä¸ä¸ªå®ç°äºä»£çæ¥å£çå¨æ代çç±»ï¼åèç ï¼ï¼åéè¿åå°æºå¶è·å¾å¨æ代çç±»çæé å½æ°ï¼å©ç¨æé å½æ°çæå¨æ代çç±»çå®ä¾å¯¹è±¡ï¼å¨è°ç¨å ·ä½æ¹æ³åè°ç¨invokeHandleræ¹æ³æ¥å¤çã
2024-11-30 14:34
2024-11-30 14:02
2024-11-30 13:54
2024-11-30 13:49
2024-11-30 13:21