Spring常è§é¢è¯é¢æ»ç»
è¿æ¯ä¸åæè®¸å¯¹ä½ æå¸®å©çä¿¡æ¯
- é¢è¯æåï¼è¿æ¯ä¸ä»½å¤§å½¬ç²¾å¿æ´çç大åé¢è¯æåææ°çï¼ç®åå·²ç»æ´æ°è¿ä»£äº19ä¸ªçæ¬ï¼è´¨éå¾é«ï¼ä¸ä¸ºé¢è¯æé ï¼
- ç¥è¯æçï¼ä¸å±é¢è¯æå/ä¸å¯¹ä¸äº¤æµ/ç®åä¿®æ¹/è¶ æ£çå¦ä¹ æ°å´/å¦ä¹ 路线è§åï¼æ¬¢è¿å å ¥å¤§å½¬çç¥è¯æçï¼ç¹å»é¾æ¥æ¥çæçç详ç»ä»ç»ï¼
Springçä¼ç¹
- éè¿æ§å¶å转åä¾èµæ³¨å ¥å®ç°æ¾è¦åã
- æ¯æé¢ååé¢çç¼ç¨ï¼å¹¶ä¸æåºç¨ä¸å¡é»è¾åç³»ç»æå¡åå¼ã
- éè¿åé¢å模æ¿åå°æ ·æ¿å¼ä»£ç ã
- 声æå¼äºå¡çæ¯æãå¯ä»¥ä»åè°ç¹åçäºå¡ç®¡ç代ç ä¸è§£è±åºæ¥ï¼éè¿å£°æå¼æ¹å¼çµæ´»å°è¿è¡äºå¡ç管çï¼æé«å¼åæçåè´¨éã
- æ¹ä¾¿éæåç§ä¼ç§æ¡æ¶ãå 鍿ä¾äºå¯¹åç§ä¼ç§æ¡æ¶çç´æ¥æ¯æï¼å¦ï¼HessianãQuartzãMyBatisçï¼ã
- æ¹ä¾¿ç¨åºçæµè¯ãSpringæ¯æJunit4ï¼æ·»å 注解便å¯ä»¥æµè¯Springç¨åºã
Spring ç¨å°äºåªäºè®¾è®¡æ¨¡å¼ï¼
1ãç®å工忍¡å¼ï¼BeanFactoryå°±æ¯ç®å工忍¡å¼çä½ç°ï¼æ ¹æ®ä¼ å
¥ä¸ä¸ªå¯ä¸æ è¯æ¥è·å¾ Bean 对象ã
@Override
public Object getBean(String name) throws BeansException {
assertBeanFactoryActive();
return getBeanFactory().getBean(name);
}
2ãå·¥åæ¹æ³æ¨¡å¼ï¼FactoryBeanå°±æ¯å
¸åçå·¥åæ¹æ³æ¨¡å¼ãspringå¨ä½¿ç¨getBean()è°ç¨è·å¾è¯¥beanæ¶ï¼ä¼èªå¨è°ç¨è¯¥beançgetObject()æ¹æ³ãæ¯ä¸ª Bean é½ä¼å¯¹åºä¸ä¸ª FactoryBeanï¼å¦ SqlSessionFactory å¯¹åº SqlSessionFactoryBeanã
3ãå便¨¡å¼ï¼ä¸ä¸ªç±»ä» æä¸ä¸ªå®ä¾ï¼æä¾ä¸ä¸ªè®¿é®å®çå ¨å±è®¿é®ç¹ãSpring å建 Bean å®ä¾é»è®¤æ¯åä¾çã
4ãéé
卿¨¡å¼ï¼SpringMVCä¸çéé
å¨HandlerAdatperãç±äºåºç¨ä¼æå¤ä¸ªControllerå®ç°ï¼å¦æéè¦ç´æ¥è°ç¨Controlleræ¹æ³ï¼é£ä¹éè¦å
夿æ¯ç±åªä¸ä¸ªControllerå¤ç请æ±ï¼ç¶åè°ç¨ç¸åºçæ¹æ³ãå½å¢å æ°ç Controllerï¼éè¦ä¿®æ¹åæ¥çé»è¾ï¼è¿åäºå¼éååï¼å¯¹ä¿®æ¹å
³éï¼å¯¹æ©å±å¼æ¾ï¼ã
为æ¤ï¼Springæä¾äºä¸ä¸ªéé
卿¥å£ï¼æ¯ä¸ç§ Controller 对åºä¸ç§ HandlerAdapter å®ç°ç±»ï¼å½è¯·æ±è¿æ¥ï¼SpringMVCä¼è°ç¨getHandler()è·åç¸åºçControllerï¼ç¶åè·å该Controller对åºç HandlerAdapterï¼æåè°ç¨HandlerAdapterçhandle()æ¹æ³å¤ç请æ±ï¼å®é
ä¸è°ç¨çæ¯ControllerçhandleRequest()ãæ¯æ¬¡æ·»å æ°ç Controller æ¶ï¼åªéè¦å¢å ä¸ä¸ªéé
å¨ç±»å°±å¯ä»¥ï¼æ éä¿®æ¹åæçé»è¾ã
常ç¨çå¤çå¨éé
å¨ï¼SimpleControllerHandlerAdapterï¼HttpRequestHandlerAdapterï¼AnnotationMethodHandlerAdapterã
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest);
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
public class HttpRequestHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {//handleræ¯è¢«éé
ç对象ï¼è¿é使ç¨çæ¯å¯¹è±¡çéé
卿¨¡å¼
return (handler instanceof HttpRequestHandler);
}
@Override
@Nullable
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
((HttpRequestHandler) handler).handleRequest(request, response);
return null;
}
}
5ãä»£çæ¨¡å¼ï¼spring ç aop 使ç¨äºå¨æä»£çï¼æä¸¤ç§æ¹å¼JdkDynamicAopProxyåCglib2AopProxyã
6ãè§å¯è
模å¼ï¼spring ä¸ observer 模å¼å¸¸ç¨çå°æ¹æ¯ listener çå®ç°ï¼å¦ApplicationListenerã
7ãæ¨¡æ¿æ¨¡å¼ï¼ Spring ä¸ jdbcTemplateãhibernateTemplate çï¼å°±ä½¿ç¨å°äºæ¨¡æ¿æ¨¡å¼ã
ä»ä¹æ¯AOPï¼
é¢ååé¢ç¼ç¨ï¼ä½ä¸ºé¢å对象çä¸ç§è¡¥å ï¼å°å ¬å ±é»è¾ï¼äºå¡ç®¡çãæ¥å¿ãç¼åçï¼å°è£ æåé¢ï¼è·ä¸å¡ä»£ç è¿è¡å离ï¼å¯ä»¥åå°ç³»ç»çéå¤ä»£ç åé使¨¡åä¹é´çè¦å度ãåé¢å°±æ¯é£äºä¸ä¸å¡æ å ³ï¼ä½ææä¸å¡æ¨¡åé½ä¼è°ç¨çå ¬å ±é»è¾ã
AOPæåªäºå®ç°æ¹å¼ï¼
AOPæä¸¤ç§å®ç°æ¹å¼ï¼éæä»£çå卿代çã
éæä»£ç
éæä»£çï¼ä»£çç±»å¨ç¼è¯é¶æ®µçæï¼å¨ç¼è¯é¶æ®µå°éç¥ç»å ¥Javaåèç ä¸ï¼ä¹ç§°ç¼è¯æ¶å¢å¼ºãAspectJ使ç¨çæ¯éæä»£çã
缺ç¹ï¼ä»£ç对象éè¦ä¸ç®æ 对象å®ç°ä¸æ ·çæ¥å£ï¼å¹¶ä¸å®ç°æ¥å£çæ¹æ³ï¼ä¼æåä½ä»£ç ãåæ¶ï¼ä¸æ¦æ¥å£å¢å æ¹æ³ï¼ç®æ 对象ä¸ä»£ç对象é½è¦ç»´æ¤ã
卿代ç
卿代çï¼ä»£çç±»å¨ç¨åºè¿è¡æ¶å建ï¼AOPæ¡æ¶ä¸ä¼å»ä¿®æ¹åèç ï¼èæ¯å¨å åä¸ä¸´æ¶çæä¸ä¸ªä»£ç对象ï¼å¨è¿è¡æé´å¯¹ä¸å¡æ¹æ³è¿è¡å¢å¼ºï¼ä¸ä¼çææ°ç±»ã
å享ä¸ä»½å¤§å½¬ç²¾å¿æ´çç大åé¢è¯æåï¼å å«è®¡ç®æºåºç¡ãJavaåºç¡ãå¤çº¿ç¨ãJVMãæ°æ®åºãRedisãSpringãMybatisãSpringMVCãSpringBootãåå¸å¼ãå¾®æå¡ã设计模å¼ãæ¶æãæ ¡æç¤¾æå享çé«é¢é¢è¯é¢ï¼é常å®ç¨ï¼æå°ä¼ä¼´é çè¿ä»½æåæ¿è¿åèoffer~
éè¦çå°ä¼ä¼´å¯ä»¥èªè¡ä¸è½½ï¼
Spring AOPçå®ç°åç
SpringçAOPå®ç°åçå
¶å®å¾ç®åï¼å°±æ¯éè¿å¨æä»£çå®ç°çã妿æä»¬ä¸ºSpringçæä¸ªbeané
ç½®äºåé¢ï¼é£ä¹Springå¨å建è¿ä¸ªbeançæ¶åï¼å®é
ä¸åå»ºçæ¯è¿ä¸ªbeançä¸ä¸ªä»£çå¯¹è±¡ï¼æä»¬åç»å¯¹bean䏿¹æ³çè°ç¨ï¼å®é
ä¸è°ç¨çæ¯ä»£çç±»éåçä»£çæ¹æ³ãèSpringçAOP使ç¨äºä¸¤ç§å¨æä»£çï¼å嫿¯JDKç卿代çï¼ä»¥åCGLibç卿代çã
JDK卿代çåCGLIB卿代ççåºå«ï¼
Spring AOPä¸ç卿代çä¸»è¦æä¸¤ç§æ¹å¼ï¼JDK卿代çåCGLIB卿代çã
JDK卿代ç
å¦æç®æ ç±»å®ç°äºæ¥å£ï¼Spring AOPä¼éæ©ä½¿ç¨JDK卿代çç®æ ç±»ã代çç±»æ ¹æ®ç®æ ç±»å®ç°çæ¥å£å¨æçæï¼ä¸éè¦èªå·±ç¼åï¼çæç卿代çç±»åç®æ ç±»é½å®ç°ç¸åçæ¥å£ãJDK卿代ççæ ¸å¿æ¯InvocationHandleræ¥å£åProxyç±»ã
缺ç¹ï¼ç®æ ç±»å¿ é¡»æå®ç°çæ¥å£ã妿æä¸ªç±»æ²¡æå®ç°æ¥å£ï¼é£ä¹è¿ä¸ªç±»å°±ä¸è½ç¨JDK卿代çã
CGLIB卿代ç
éè¿ç»§æ¿å®ç°ãå¦æç®æ 类没æå®ç°æ¥å£ï¼é£ä¹Spring AOPä¼éæ©ä½¿ç¨CGLIBæ¥å¨æä»£çç®æ ç±»ãCGLIBï¼Code Generation Libraryï¼å¯ä»¥å¨è¿è¡æ¶å¨æçæç±»çåèç ï¼å¨æåå»ºç®æ ç±»çå类对象ï¼å¨å类对象ä¸å¢å¼ºç®æ ç±»ã
CGLIBæ¯éè¿ç»§æ¿çæ¹å¼åç卿代çï¼å æ¤å¦ææä¸ªç±»è¢«æ 记为finalï¼é£ä¹å®æ¯æ æ³ä½¿ç¨CGLIBå卿代ççã
ä¼ç¹ï¼ç®æ ç±»ä¸éè¦å®ç°ç¹å®çæ¥å£ï¼æ´å çµæ´»ã
ä»ä¹æ¶åéç¨åªç§å¨æä»£çï¼
- å¦æç®æ 对象å®ç°äºæ¥å£ï¼é»è®¤æ åµä¸ä¼éç¨JDKç卿代çå®ç°AOP
- å¦æç®æ 对象å®ç°äºæ¥å£ï¼å¯ä»¥å¼ºå¶ä½¿ç¨CGLIBå®ç°AOP
- å¦æç®æ 对象没æå®ç°äºæ¥å£ï¼å¿ é¡»éç¨CGLIBåº
两è çåºå«ï¼
- jdk卿代ç使ç¨jdkä¸çç±»Proxyæ¥å建代ç对象ï¼å®ä½¿ç¨åå°ææ¯æ¥å®ç°ï¼ä¸éè¦å¯¼å
¥å
¶ä»ä¾èµãcglibéè¦å¼å
¥ç¸å
³ä¾èµï¼
asm.jarï¼å®ä½¿ç¨åèç å¢å¼ºææ¯æ¥å®ç°ã - å½ç®æ ç±»å®ç°äºæ¥å£çæ¶åSpring Aopé»è®¤ä½¿ç¨jdkå¨æä»£çæ¹å¼æ¥å¢å¼ºæ¹æ³ï¼æ²¡æå®ç°æ¥å£çæ¶å使ç¨cglibå¨æä»£çæ¹å¼å¢å¼ºæ¹æ³ã
Spring AOPç¸å ³æ¯è¯
ï¼1ï¼åé¢ï¼Aspectï¼ï¼å颿¯éç¥ååç¹çç»åãéç¥ååç¹å ±åå®ä¹äºåé¢çå ¨é¨å 容ã
ï¼2ï¼è¿æ¥ç¹ï¼Join pointï¼ï¼ææ¹æ³ï¼å¨Spring AOPä¸ï¼ä¸ä¸ªè¿æ¥ç¹æ»æ¯ä»£è¡¨ä¸ä¸ªæ¹æ³çæ§è¡ãè¿æ¥ç¹æ¯å¨åºç¨æ§è¡è¿ç¨ä¸è½å¤æå ¥åé¢çä¸ä¸ªç¹ãè¿ä¸ªç¹å¯ä»¥æ¯è°ç¨æ¹æ³æ¶ãæåºå¼å¸¸æ¶ãçè³ä¿®æ¹ä¸ä¸ªå段æ¶ãåé¢ä»£ç å¯ä»¥å©ç¨è¿äºç¹æå ¥å°åºç¨çæ£å¸¸æµç¨ä¹ä¸ï¼å¹¶æ·»å æ°çè¡ä¸ºã
ï¼3ï¼éç¥ï¼Adviceï¼ï¼å¨AOPæ¯è¯ä¸ï¼åé¢çå·¥ä½è¢«ç§°ä¸ºéç¥ã
ï¼4ï¼åå ¥ç¹ï¼Pointcutï¼ï¼åç¹çå®ä¹ä¼å¹é éç¥æè¦ç»å ¥çä¸ä¸ªæå¤ä¸ªè¿æ¥ç¹ãæä»¬éå¸¸ä½¿ç¨æç¡®çç±»åæ¹æ³åç§°ï¼ææ¯å©ç¨æ£å表达å¼å®ä¹æå¹é çç±»åæ¹æ³åç§°æ¥æå®è¿äºåç¹ã
ï¼5ï¼å¼å ¥ï¼Introductionï¼ï¼å¼å ¥å 许æä»¬åç°æç±»æ·»å æ°æ¹æ³æå±æ§ã
ï¼6ï¼ç®æ 对象ï¼Target Objectï¼ï¼ 被ä¸ä¸ªæè å¤ä¸ªåé¢ï¼aspectï¼æéç¥ï¼adviseï¼ç对象ãå®é常æ¯ä¸ä¸ªä»£ç对象ã
ï¼7ï¼ç»å ¥ï¼Weavingï¼ï¼ç»å ¥æ¯æåé¢åºç¨å°ç®æ 对象并å建æ°ç代ç对象çè¿ç¨ãå¨ç®æ 对象ççå½å¨æéæä»¥ä¸æ¶é´ç¹å¯ä»¥è¿è¡ç»å ¥ï¼
- ç¼è¯æï¼åé¢å¨ç®æ ç±»ç¼è¯æ¶è¢«ç»å ¥ãAspectJçç»å ¥ç¼è¯å¨æ¯ä»¥è¿ç§æ¹å¼ç»å ¥åé¢çã
- ç±»å è½½æï¼åé¢å¨ç®æ ç±»å è½½å°JVMæ¶è¢«ç»å ¥ãéè¦ç¹æ®çç±»å è½½å¨ï¼å®å¯ä»¥å¨ç®æ 类被å¼å ¥åºç¨ä¹åå¢å¼ºè¯¥ç®æ ç±»çåèç ãAspectJ5çå è½½æ¶ç»å ¥å°±æ¯æä»¥è¿ç§æ¹å¼ç»å ¥åé¢ã
- è¿è¡æï¼åé¢å¨åºç¨è¿è¡çæä¸ªæ¶å»è¢«ç»å ¥ãä¸è¬æ åµä¸ï¼å¨ç»å ¥å颿¶ï¼AOP容å¨ä¼ä¸ºç®æ å¯¹è±¡å¨æå°å建ä¸ä¸ªä»£ç对象ãSpringAOPå°±æ¯ä»¥è¿ç§æ¹å¼ç»å ¥åé¢ã
Springéç¥æåªäºç±»åï¼
å¨AOPæ¯è¯ä¸ï¼åé¢çå·¥ä½è¢«ç§°ä¸ºéç¥ãéç¥å®é 䏿¯ç¨åºè¿è¡æ¶è¦éè¿Spring AOPæ¡æ¶æ¥è§¦åçä»£ç æ®µã
Springåé¢å¯ä»¥åºç¨5ç§ç±»åçéç¥ï¼
- åç½®éç¥ï¼Beforeï¼ï¼å¨ç®æ æ¹æ³è¢«è°ç¨ä¹åè°ç¨éç¥åè½ï¼
- åç½®éç¥ï¼Afterï¼ï¼å¨ç®æ æ¹æ³å®æä¹åè°ç¨éç¥ï¼æ¤æ¶ä¸ä¼å ³å¿æ¹æ³çè¾åºæ¯ä»ä¹ï¼
- è¿åéç¥ï¼After-returning ï¼ï¼å¨ç®æ æ¹æ³æåæ§è¡ä¹åè°ç¨éç¥ï¼
- å¼å¸¸éç¥ï¼After-throwingï¼ï¼å¨ç®æ æ¹æ³æåºå¼å¸¸åè°ç¨éç¥ï¼
- ç¯ç»éç¥ï¼Aroundï¼ï¼éç¥å 裹äºè¢«éç¥çæ¹æ³ï¼å¨è¢«éç¥çæ¹æ³è°ç¨ä¹ååè°ç¨ä¹åæ§è¡èªå®ä¹çé»è¾ã
ä»ä¹æ¯IOCï¼
IOCï¼æ§å¶å转ï¼ç±Spring容å¨ç®¡çbeançæ´ä¸ªçå½å¨æãéè¿åå°å®ç°å¯¹å ¶ä»å¯¹è±¡çæ§å¶ï¼å æ¬åå§åãå建ã鿝çï¼è§£æ¾æå¨å建对象çè¿ç¨ï¼åæ¶éä½ç±»ä¹é´çè¦å度ã
IOCç好å¤ï¼
iocçææ³ææ ¸å¿çå°æ¹å¨äºï¼èµæºä¸ç±ä½¿ç¨èµæºè 管çï¼èç±ä¸ä½¿ç¨èµæºçç¬¬ä¸æ¹ç®¡çï¼è¿å¯ä»¥å¸¦æ¥å¾å¤å¥½å¤ã第ä¸ï¼èµæºéä¸ç®¡çï¼å®ç°èµæºçå¯é ç½®åæç®¡çã第äºï¼éä½äºä½¿ç¨èµæºåæ¹çä¾èµç¨åº¦ï¼ä¹å°±æ¯æä»¬è¯´çè¦å度ã
ä¹å°±æ¯è¯´ï¼ç²æ¹è¦è¾¾ææç§ç®çä¸éè¦ç´æ¥ä¾èµä¹æ¹ï¼å®åªéè¦è¾¾å°çç®çåè¯ç¬¬ä¸æ¹æºæå°±å¯ä»¥äºï¼æ¯å¦ç²æ¹éè¦ä¸åè¢åï¼è乿¹å®åä¸åè¢åï¼å®è¦æè¢åååºå»ï¼å¹¶ä¸éè¦èªå·±å»ç´æ¥æ¾å°ä¸ä¸ªåå®¶æ¥å®æè¢åçååºãå®ä¹åªéè¦æ¾ç¬¬ä¸æ¹ï¼åè¯å«äººæè¦åä¸åè¢åãè¿ä¸å¥½äºï¼ç²ä¹åæ¹è¿è¡äº¤ææ´»å¨ï¼é½ä¸éè¦èªå·±ç´æ¥å»æ¾åå®¶ï¼ç¸å½äºç¨åºå é¨å¼æ¾æ¥å£ï¼åå®¶ç±ç¬¬ä¸æ¹ä½ä¸ºåæ°ä¼ å ¥ãç²ä¹äºç¸ä¸ä¾èµï¼èä¸åªæå¨è¿è¡äº¤ææ´»å¨çæ¶åï¼ç²æåä¹äº§çèç³»ãåä¹äº¦ç¶ãè¿æ ·åä»ä¹å¥½å¤ä¹å¢ï¼ç²ä¹å¯ä»¥å¨å¯¹æ¹ä¸çå®åå¨çæ åµä¸ç¬ç«åå¨ï¼èä¸ä¿è¯ä¸äº¤ææ¶åæ èç³»ï¼æ³äº¤æçæ¶åå¯ä»¥å¾å®¹æç产çèç³»ãç²ä¹äº¤ææ´»å¨ä¸éè¦åæ¹è§é¢ï¼é¿å äºåæ¹çäºä¸ä¿¡ä»»é æäº¤æå¤±è´¥çé®é¢ãå 为交æç±ç¬¬ä¸æ¹æ¥è´è´£èç³»ï¼èä¸ç²ä¹é½è®¤ä¸ºç¬¬ä¸æ¹å¯é ãé£ä¹äº¤æå°±è½å¾å¯é å¾çµæ´»ç产çåè¿è¡äºã
è¿å°±æ¯iocçæ ¸å¿ææ³ãçæ´»ä¸è¿ç§ä¾åæ¯æ¯çæ¯ï¼æ¯ä»å®å¨æ´ä¸ªæ·å®ä½ç³»éå°±æ¯åºå¤§çioc容å¨ï¼äº¤æåæ¹ä¹å¤çç¬¬ä¸æ¹ï¼æä¾å¯é æ§å¯ä¾èµå¯çµæ´»åæ´äº¤ææ¹çèµæºç®¡çä¸å¿ãå¦å¤äººäºä»£ç乿¯ï¼éä½£æºæå个人ä¹å¤çç¬¬ä¸æ¹ã
åè龿¥ï¼https://www.zhihu.com/question/23277575/answer/24259844
ä»ä¹æ¯ä¾èµæ³¨å ¥ï¼
å¨Springå建对象çè¿ç¨ä¸ï¼æå¯¹è±¡ä¾èµç屿§æ³¨å ¥å°å¯¹è±¡ä¸ãä¾èµæ³¨å ¥ä¸»è¦æä¸¤ç§æ¹å¼ï¼æé 卿³¨å ¥å屿§æ³¨å ¥ã
IOC容å¨åå§åè¿ç¨ï¼
- ä»XMLä¸è¯»åé ç½®æä»¶ã
- å°beanæ ç¾è§£ææ BeanDefinitionï¼å¦è§£æ property å ç´ ï¼ å¹¶æ³¨å ¥å° BeanDefinition å®ä¾ä¸ã
- å° BeanDefinition 注åå°å®¹å¨ BeanDefinitionMap ä¸ã
- BeanFactory æ ¹æ® BeanDefinition çå®ä¹ä¿¡æ¯å建å®ä¾åååå§å beanã
åä¾beançåå§å以åä¾èµæ³¨å ¥ä¸è¬é½å¨å®¹å¨åå§åé¶æ®µè¿è¡ï¼åªææå è½½ï¼lazy-init为trueï¼çåä¾beanæ¯å¨åºç¨ç¬¬ä¸æ¬¡è°ç¨getBean()æ¶è¿è¡åå§ååä¾èµæ³¨å ¥ã
// AbstractApplicationContext
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
å¤ä¾bean å¨å®¹å¨å¯å¨æ¶ä¸å®ä¾åï¼å³ä½¿è®¾ç½® lazy-init 为 false 乿²¡ç¨ï¼åªæè°ç¨äºgetBean()æè¿è¡å®ä¾åã
loadBeanDefinitionséç¨äºæ¨¡æ¿æ¨¡å¼ï¼å
·ä½å è½½ BeanDefinition çé»è¾ç±å个åç±»å®æã
Beanççå½å¨æ

1.è°ç¨beançæé æ¹æ³å建Bean
2.éè¿åå°è°ç¨setteræ¹æ³è¿è¡å±æ§çä¾èµæ³¨å ¥
3.妿Beanå®ç°äºBeanNameAwareæ¥å£ï¼Springå°è°ç¨setBeanName()ï¼è®¾ç½® Beançnameï¼xmlæä»¶ä¸beanæ ç¾çidï¼
4.妿Beanå®ç°äºBeanFactoryAwareæ¥å£ï¼Springå°è°ç¨setBeanFactory()æbean factory设置ç»Bean
5.妿åå¨BeanPostProcessorï¼Springå°è°ç¨å®ä»¬çpostProcessBeforeInitializationï¼é¢åå§åï¼æ¹æ³ï¼å¨Beanåå§åå对å
¶è¿è¡å¤ç
6.妿Beanå®ç°äºInitializingBeanæ¥å£ï¼Springå°è°ç¨å®çafterPropertiesSetæ¹æ³ï¼ç¶åè°ç¨xmlå®ä¹ç init-method æ¹æ³ï¼ä¸¤ä¸ªæ¹æ³ä½ç¨ç±»ä¼¼ï¼é½æ¯å¨åå§å bean çæ¶åæ§è¡
7.妿åå¨BeanPostProcessorï¼Springå°è°ç¨å®ä»¬çpostProcessAfterInitializationï¼ååå§åï¼æ¹æ³ï¼å¨Beanåå§åå对å
¶è¿è¡å¤ç
8.Beanåå§å宿ï¼ä¾åºç¨ä½¿ç¨ï¼è¿éåä¸¤ç§æ åµï¼
8.1 妿Bean为åä¾çè¯ï¼é£ä¹å®¹å¨ä¼è¿åBeanç»ç¨æ·ï¼å¹¶åå
¥ç¼åæ± ã妿Beanå®ç°äºDisposableBeanæ¥å£ï¼Springå°è°ç¨å®çdestoryæ¹æ³ï¼ç¶åè°ç¨å¨xmlä¸å®ä¹ç destory-methodæ¹æ³ï¼è¿ä¸¤ä¸ªæ¹æ³ä½ç¨ç±»ä¼¼ï¼é½æ¯å¨Beanå®ä¾éæ¯åæ§è¡ã
8.2 妿Beanæ¯å¤ä¾çè¯ï¼å®¹å¨å°Beanè¿åç»ç¨æ·ï¼å©ä¸ççå½å¨æç±ç¨æ·æ§å¶ã
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
BeanFactoryåFactoryBeançåºå«ï¼
BeanFactoryï¼ç®¡çBeanç容å¨ï¼Springä¸çæçBean齿¯ç±è¿ä¸ªæ¥å£çå®ç°æ¥ç®¡ççã
FactoryBeanï¼é常æ¯ç¨æ¥å建æ¯è¾å¤æçbeanï¼ä¸è¬çbean ç´æ¥ç¨xmlé ç½®å³å¯ï¼ä½å¦æä¸ä¸ªbeançå建è¿ç¨ä¸æ¶åå°å¾å¤å ¶ä»çbean å夿çé»è¾ï¼ç´æ¥ç¨xmlé ç½®æ¯è¾éº»ç¦ï¼è¿æ¶å¯ä»¥èèç¨FactoryBeanï¼å¯ä»¥éèå®ä¾å夿Beançç»èã
å½é ç½®æä»¶ä¸beanæ ç¾çclass屿§é ç½®çå®ç°ç±»æ¯FactoryBeanæ¶ï¼éè¿ getBean()æ¹æ³è¿åç䏿¯FactoryBeanæ¬èº«ï¼èæ¯è°ç¨FactoryBean#getObject()æ¹æ³æè¿åç对象ï¼ç¸å½äºFactoryBean#getObject()代çäºgetBean()æ¹æ³ã妿æ³å¾å°FactoryBeanå¿ é¡»ä½¿ç¨ '&' + beanName çæ¹å¼è·åã
Mybatis æä¾äº SqlSessionFactoryBeanï¼å¯ä»¥ç®å SqlSessionFactoryçé
ç½®ï¼
public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> {
@Override
public void afterPropertiesSet() throws Exception {
notNull(dataSource, "Property 'dataSource' is required");
notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");
state((configuration == null && configLocation == null) || !(configuration != null && configLocation != null),
"Property 'configuration' and 'configLocation' can not specified with together");
this.sqlSessionFactory = buildSqlSessionFactory();
}
protected SqlSessionFactory buildSqlSessionFactory() throws IOException {
//夿é»è¾
}
@Override
public SqlSessionFactory getObject() throws Exception {
if (this.sqlSessionFactory == null) {
afterPropertiesSet();
}
return this.sqlSessionFactory;
}
}
å¨ xml é ç½® SqlSessionFactoryBeanï¼
<bean id="tradeSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="trade" />
<property name="mapperLocations" value="classpath*:mapper/trade/*Mapper.xml" />
<property name="configLocation" value="classpath:mybatis-config.xml" />
<property name="typeAliasesPackage" value="com.bytebeats.mybatis3.domain.trade" />
</bean>
Spring å°ä¼å¨åºç¨å¯å¨æ¶å建 SqlSessionFactoryï¼å¹¶ä½¿ç¨ sqlSessionFactory è¿ä¸ªåååå¨èµ·æ¥ã
BeanFactoryåApplicationContextæä»ä¹åºå«ï¼
BeanFactoryåApplicationContextæ¯Springçä¸¤å¤§æ ¸å¿æ¥å£ï¼é½å¯ä»¥å½åSpringç容å¨ãå ¶ä¸ApplicationContextæ¯BeanFactoryç忥å£ã
两è åºå«å¦ä¸ï¼
1ãåè½ä¸çåºå«ãBeanFactoryæ¯Springé颿åºå±çæ¥å£ï¼å å«äºåç§Beançå®ä¹ï¼è¯»åbeané ç½®ææ¡£ï¼ç®¡çbeançå è½½ãå®ä¾åï¼æ§å¶beanççå½å¨æï¼ç»´æ¤beanä¹é´çä¾èµå ³ç³»ã
ApplicationContextæ¥å£ä½ä¸ºBeanFactoryçæ´¾çï¼é¤äºæä¾BeanFactoryæå ·æçåè½å¤ï¼è¿æä¾äºæ´å®æ´çæ¡æ¶åè½ï¼å¦ç»§æ¿MessageSourceãæ¯æå½é åãç»ä¸çèµæºæä»¶è®¿é®æ¹å¼ãåæ¶å è½½å¤ä¸ªé ç½®æä»¶çåè½ã
2ãå è½½æ¹å¼çåºå«ãBeanFactroyéç¨çæ¯å»¶è¿å è½½å½¢å¼æ¥æ³¨å ¥Beançï¼å³åªæå¨ä½¿ç¨å°æä¸ªBeanæ¶(è°ç¨getBean())ï¼æå¯¹è¯¥Beanè¿è¡å è½½å®ä¾åãè¿æ ·ï¼æä»¬å°±ä¸è½åç°ä¸äºåå¨çSpringçé ç½®é®é¢ã妿Beançæä¸ä¸ªå±æ§æ²¡ææ³¨å ¥ï¼BeanFacotryå è½½åï¼ç´è³ç¬¬ä¸æ¬¡ä½¿ç¨è°ç¨getBeanæ¹æ³æä¼æåºå¼å¸¸ã
èApplicationContextæ¯å¨å®¹å¨å¯å¨æ¶ï¼ä¸æ¬¡æ§åå»ºäºææçBeanãè¿æ ·ï¼å¨å®¹å¨å¯å¨æ¶ï¼æä»¬å°±å¯ä»¥åç°Springä¸åå¨çé ç½®é误ï¼è¿æ ·æå©äºæ£æ¥æä¾èµå±æ§æ¯å¦æ³¨å ¥ã ApplicationContextå¯å¨åé¢è½½å ¥ææçåä¾Beanï¼é£ä¹å¨éè¦çæ¶åï¼ä¸éè¦çå¾ å建beanï¼å 为å®ä»¬å·²ç»å建好äºã
ç¸å¯¹äºåºæ¬çBeanFactoryï¼ApplicationContext å¯ä¸çä¸è¶³æ¯å ç¨å å空é´ãå½åºç¨ç¨åºé ç½®Beanè¾å¤æ¶ï¼ç¨åºå¯å¨è¾æ ¢ã
3ãå建æ¹å¼çåºå«ãBeanFactoryé常以ç¼ç¨çæ¹å¼è¢«å建ï¼ApplicationContextè¿è½ä»¥å£°æçæ¹å¼å建ï¼å¦ä½¿ç¨ContextLoaderã
4ãæ³¨åæ¹å¼çåºå«ãBeanFactoryåApplicationContext齿¯æBeanPostProcessorãBeanFactoryPostProcessorç使ç¨ï¼ä½ä¸¤è ä¹é´çåºå«æ¯ï¼BeanFactoryéè¦æå¨æ³¨åï¼èApplicationContext忝èªå¨æ³¨åã
Beanæ³¨å ¥å®¹å¨æåªäºæ¹å¼ï¼
1ã@Configuration + @Bean
@Configurationç¨æ¥å£°æä¸ä¸ªé 置类ï¼ç¶åä½¿ç¨ @Bean 注解ï¼ç¨äºå£°æä¸ä¸ªbeanï¼å°å ¶å å ¥å°Spring容å¨ä¸ã
@Configuration
public class MyConfiguration {
@Bean
public Person person() {
Person person = new Person();
person.setName("大彬");
return person;
}
}
2ãéè¿å æ«æç¹å®æ³¨è§£çæ¹å¼
@ComponentScanæ¾ç½®å¨æä»¬çé 置类ä¸ï¼ç¶åå¯ä»¥æå®ä¸ä¸ªè·¯å¾ï¼è¿è¡æ«æå¸¦æç¹å®æ³¨è§£çbeanï¼ç¶åå è³å®¹å¨ä¸ã
ç¹å®æ³¨è§£å æ¬@Controllerã@Serviceã@Repositoryã@Component
@Component
public class Person {
//...
}
@ComponentScan(basePackages = "com.dabin.test.*")
public class Demo1 {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class);
Person bean = applicationContext.getBean(Person.class);
System.out.println(bean);
}
}
3ã@Importæ³¨è§£å¯¼å ¥
@Import注解平æ¶å¼åç¨çä¸å¤ï¼ä½æ¯ä¹æ¯é常éè¦çï¼å¨è¿è¡Springæ©å±æ¶ç»å¸¸ä¼ç¨å°ï¼å®ç»å¸¸æé èªå®ä¹æ³¨è§£è¿è¡ä½¿ç¨ï¼ç¶åå¾å®¹å¨ä¸å¯¼å ¥ä¸ä¸ªé ç½®æä»¶ã
@ComponentScan
/*æç¨å°çèµæºå¯¼å
¥å°å½å容å¨ä¸*/
@Import({Person.class})
public class App {
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(App.class, args);
System.out.println(context.getBean(Person.class));
context.close();
}
}
4ãå®ç°BeanDefinitionRegistryPostProcessorè¿è¡åç½®å¤çã
å¨Spring容å¨å¯å¨çæ¶å伿§è¡ BeanDefinitionRegistryPostProcessor ç postProcessBeanDefinitionRegistry æ¹æ³ï¼å°±æ¯çbeanDefinitionå è½½å®æ¯ä¹åï¼å¯¹beanDefinitionè¿è¡åç½®å¤çï¼å¯ä»¥å¨æ¤è¿è¡è°æ´IOC容å¨ä¸çbeanDefinitionï¼ä»èå¹²æ°å°åé¢è¿è¡åå§åbeanã
å¨ä¸é¢ç代ç ä¸ï¼æä»¬æå¨åbeanDefinitionRegistry䏿³¨åäºpersonçBeanDefinitionãæç»æåå°personå å ¥å°applicationContextä¸ã
public class Demo1 {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
MyBeanDefinitionRegistryPostProcessor beanDefinitionRegistryPostProcessor = new MyBeanDefinitionRegistryPostProcessor();
applicationContext.addBeanFactoryPostProcessor(beanDefinitionRegistryPostProcessor);
applicationContext.refresh();
Person bean = applicationContext.getBean(Person.class);
System.out.println(bean);
}
}
class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Person.class).getBeanDefinition();
registry.registerBeanDefinition("person", beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
5ã使ç¨FactoryBeanæ¥å£
å¦ä¸å¾ä»£ç ï¼ä½¿ç¨@Configuration + @Beançæ¹å¼å° PersonFactoryBean å å ¥å°å®¹å¨ä¸ï¼è¿é没æå容å¨ä¸ç´æ¥æ³¨å ¥ Personï¼èæ¯æ³¨å ¥ PersonFactoryBeanï¼ç¶åä»å®¹å¨ä¸æ¿Personè¿ä¸ªç±»åçbeanã
@Configuration
public class Demo1 {
@Bean
public PersonFactoryBean personFactoryBean() {
return new PersonFactoryBean();
}
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class);
Person bean = applicationContext.getBean(Person.class);
System.out.println(bean);
}
}
class PersonFactoryBean implements FactoryBean<Person> {
@Override
public Person getObject() throws Exception {
return new Person();
}
@Override
public Class<?> getObjectType() {
return Person.class;
}
}
Beançä½ç¨å
1ãsingletonï¼åä¾ï¼Springä¸çbeané»è®¤é½æ¯åä¾çã
2ãprototypeï¼æ¯æ¬¡è¯·æ±é½ä¼å建ä¸ä¸ªæ°çbeanå®ä¾ã
3ãrequestï¼æ¯ä¸æ¬¡HTTP请æ±é½ä¼äº§çä¸ä¸ªæ°çbeanï¼è¯¥beanä» å¨å½åHTTP requestå ææã
4ãsessionï¼æ¯ä¸æ¬¡HTTP请æ±é½ä¼äº§çä¸ä¸ªæ°çbeanï¼è¯¥beanä» å¨å½åHTTP sessionå ææã
5ãglobal-sessionï¼å ¨å±sessionä½ç¨åã
Springèªå¨è£ é çæ¹å¼æåªäºï¼
Springçèªå¨è£ é æä¸ç§æ¨¡å¼ï¼byType(æ ¹æ®ç±»å)ï¼byName(æ ¹æ®åç§°)ãconstructor(æ ¹æ®æé 彿°)ã
byType
æ¾å°ä¸ä¾èµç±»åç¸åçbeanæ³¨å ¥å°å¦å¤çbeanä¸ï¼è¿ä¸ªè¿ç¨éè¦åå©setteræ³¨å ¥æ¥å®æï¼å æ¤å¿ é¡»åå¨setæ¹æ³ï¼å¦åæ³¨å ¥å¤±è´¥ã
å½xmlæä»¶ä¸åå¨å¤ä¸ªç¸åç±»ååç§°ä¸åçå®ä¾Beanæ¶ï¼Spring容å¨ä¾èµæ³¨å
¥ä»ç¶ä¼å¤±è´¥ï¼å 为åå¨å¤ç§éåçé项ï¼Spring容卿 æ³ç¥é该注å
¥é£ç§ï¼æ¤æ¶æä»¬éè¦ä¸ºSpring容卿ä¾å¸®å©ï¼æå®æ³¨å
¥é£ä¸ªBeanå®ä¾ãå¯ä»¥éè¿ï¼beanï¼æ ç¾çautowire-candidate设置为falseæ¥è¿æ»¤é£äºä¸éè¦æ³¨å
¥çå®ä¾Bean
<bean id="userDao" class="com.zejian.spring.springIoc.dao.impl.UserDaoImpl" />
<!-- autowire-candidate="false" è¿æ»¤è¯¥ç±»å -->
<bean id="userDao2" autowire-candidate="false" class="com.zejian.spring.springIoc.dao.impl.UserDaoImpl" />
<!-- byType æ ¹æ®ç±»åèªå¨è£
é
userDao-->
<bean id="userService" autowire="byType" class="com.zejian.spring.springIoc.service.impl.UserServiceImpl" />
byName
å°å±æ§åä¸beanåç§°è¿è¡å¹é ï¼å¦ææ¾å°åæ³¨å ¥ä¾èµbeanã
<bean id="userDao" class="com.zejian.spring.springIoc.dao.impl.UserDaoImpl" />
<bean id="userDao2" class="com.zejian.spring.springIoc.dao.impl.UserDaoImpl" />
<!-- byName æ ¹æ®åç§°èªå¨è£
é
ï¼æ¾å°UserServiceImplå为 userDao屿§å¹¶æ³¨å
¥-->
<bean id="userService" autowire="byName" class="com.zejian.spring.springIoc.service.impl.UserServiceImpl" />
constructor
åå¨å个å®ä¾åä¼å æç±»åè¿è¡åæ°å¹é ï¼æ 论åç§°æ¯å¦å¹é ï¼ï¼å½åå¨å¤ä¸ªç±»åç¸åå®ä¾æ¶ï¼æåç§°ä¼å å¹é ï¼å¦ææ²¡ææ¾å°å¯¹åºåç§°ï¼åæ³¨å ¥å¤±è´¥ã
@Autowiredå@Resourceçåºå«ï¼
Autowireæ¯springçæ³¨è§£ãé»è®¤æ
åµä¸@Autowiredæ¯æç±»åå¹é
ç(byType)ã妿éè¦æåç§°(byName)å¹é
çè¯ï¼å¯ä»¥ä½¿ç¨@Qualifier注解ä¸@Autowiredç»åã@Autowired å¯ä»¥ä¼ éä¸ä¸ªrequired=falseç屿§ï¼falseææå½userDaoå®ä¾åå¨å°±æ³¨å
¥ä¸å就忽ç¥ï¼å¦æä¸ºtrueï¼å°±å¿
须注å
¥ï¼è¥userDaoå®ä¾ä¸åå¨ï¼å°±æåºå¼å¸¸ã
public class UserServiceImpl implements UserService {
//æ æ³¨æååé
@Autowired
@Qualifier("userDao1")
private UserDao userDao;
}
Resourceæ¯j2eeçæ³¨è§£ï¼é»è®¤æ byName模å¼èªå¨æ³¨å ¥ã@Resourceæä¸¤ä¸ªä¸éè¦ç屿§ï¼nameåtypeãname屿§æå®beançååï¼type屿§åæå®beançç±»åãå æ¤ä½¿ç¨name屿§ï¼åæbyName模å¼çèªå¨æ³¨å ¥çç¥ï¼å¦æä½¿ç¨type屿§ï¼åæ byType模å¼èªå¨æ³¨å ¥çç¥ãåè¥æ¢ä¸æå®nameä¹ä¸æå®type屿§ï¼Spring容å¨å°éè¿åå°ææ¯é»è®¤æbyNameæ¨¡å¼æ³¨å ¥ã
@Resource(name="userDao")
private UserDao userDao;//ç¨äºæååé
//ä¹å¯ä»¥ç¨äºsetæ¹æ³æ 注
@Resource(name="userDao")
public void setUserDao(UserDao userDao) {
this.userDao= userDao;
}
ä¸è¿°ä¸¤ç§èªå¨è£ é çä¾èµæ³¨å ¥å¹¶ä¸éåç®åå¼ç±»åï¼å¦intãbooleanãlongãString以åEnumçï¼å¯¹äºè¿äºç±»åï¼Spring容å¨ä¹æä¾äº@Valueæ³¨å ¥çæ¹å¼ã
@Valueå@Autowiredã@Resource类似ï¼ä¹æ¯ç¨æ¥å¯¹å±æ§è¿è¡æ³¨å ¥çï¼åªä¸è¿@Valueæ¯ç¨æ¥ä»Propertiesæä»¶ä¸æ¥è·åå¼çï¼å¹¶ä¸@Valueå¯ä»¥è§£æSpEL(Spring表达å¼)ã
æ¯å¦ï¼jdbc.propertiesæä»¶å¦ä¸ï¼
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8&allowMultiQueries=true
jdbc.username=root
jdbc.password=root
å©ç¨æ³¨è§£@Valueè·åjdbc.urlåjdbc.usernameçå¼ï¼å®ç°å¦ä¸ï¼
public class UserServiceImpl implements UserService {
//å ä½ç¬¦æ¹å¼
@Value("${jdbc.url}")
private String url;
//SpEL表达æ¹å¼ï¼å
¶ä¸ä»£è¡¨xmlé
ç½®æä»¶ä¸çidå¼configProperties
@Value("#{configProperties['jdbc.username']}")
private String userName;
}
@Qualifier 注解æä»ä¹ä½ç¨
å½éè¦å建å¤ä¸ªç¸åç±»åç bean 并叿ä»
使ç¨å±æ§è£
é
å
¶ä¸ä¸ä¸ª bean æ¶ï¼å¯ä»¥ä½¿ç¨@Qualifier 注解å @Autowired éè¿æå®åºè¯¥è£
é
åªä¸ª bean æ¥æ¶é¤æ§ä¹ã
@Beanå@Componentæä»ä¹åºå«ï¼
齿¯ä½¿ç¨æ³¨è§£å®ä¹ Beanã@Bean æ¯ä½¿ç¨ Java 代ç è£ é Beanï¼@Component æ¯èªå¨è£ é Beanã
@Component 注解ç¨å¨ç±»ä¸ï¼è¡¨æä¸ä¸ªç±»ä¼ä½ä¸ºç»ä»¶ç±»ï¼å¹¶åç¥Springè¦ä¸ºè¿ä¸ªç±»å建beanï¼æ¯ä¸ªç±»å¯¹åºä¸ä¸ª Beanã
@Bean 注解ç¨å¨æ¹æ³ä¸ï¼è¡¨ç¤ºè¿ä¸ªæ¹æ³ä¼è¿åä¸ä¸ª Beanã@Bean éè¦å¨é 置类ä¸ä½¿ç¨ï¼å³ç±»ä¸éè¦å ä¸@Configuration注解ã
@Component
public class Student {
private String name = "lkm";
public String getName() {
return name;
}
}
@Configuration
public class WebSocketConfig {
@Bean
public Student student(){
return new Student();
}
}
@Bean 注解æ´å çµæ´»ãå½éè¦å°ç¬¬ä¸æ¹ç±»è£ é å° Spring 容å¨ä¸ï¼å ä¸ºæ²¡åæ³æºä»£ç 䏿·»å @Component注解ï¼åªè½ä½¿ç¨@Bean æ³¨è§£çæ¹å¼ï¼å½ç¶ä¹å¯ä»¥ä½¿ç¨ xml çæ¹å¼ã
@Componentã@Controllerã@Repositorå@Service çåºå«ï¼
@Componentï¼ææ®éçç»ä»¶ï¼å¯ä»¥è¢«æ³¨å ¥å°spring容å¨è¿è¡ç®¡çã
@Controllerï¼å°ç±»æ 记为 Spring Web MVC æ§å¶å¨ã
@Serviceï¼å°ç±»æ 记为ä¸å¡å±ç»ä»¶ã
@Repositoryï¼å°ç±»æ è®°ä¸ºæ°æ®è®¿é®ç»ä»¶ï¼å³DAOç»ä»¶ã
Spring äºå¡å®ç°æ¹å¼æåªäºï¼
äºå¡å°±æ¯ä¸ç³»åçæä½ååæ§è¡ãSpringäºå¡æºå¶ä¸»è¦å æ¬å£°æå¼äºå¡åç¼ç¨å¼äºå¡ã
- ç¼ç¨å¼äºå¡ï¼éè¿ç¼ç¨çæ¹å¼ç®¡çäºå¡ï¼è¿ç§æ¹å¼å¸¦æ¥äºå¾å¤§ççµæ´»æ§ï¼ä½å¾é¾ç»´æ¤ã
- 声æå¼äºå¡ï¼å°äºå¡ç®¡ç代ç ä»ä¸å¡æ¹æ³ä¸åç¦»åºæ¥ï¼éè¿aopè¿è¡å°è£
ãSpring声æå¼äºå¡ä½¿å¾æä»¬æ éè¦å»å¤çè·å¾è¿æ¥ãå
³éè¿æ¥ãäºå¡æäº¤ååæ»çè¿äºæä½ã使ç¨
@Transactional注解å¼å¯å£°æå¼äºå¡ã
@Transactionalç¸å
³å±æ§å¦ä¸ï¼
| 屿§ | ç±»å | æè¿° |
|---|---|---|
| value | String | å¯éçéå®æè¿°ç¬¦ï¼æå®ä½¿ç¨çäºå¡ç®¡çå¨ |
| propagation | enum: Propagation | å¯éçäºå¡ä¼ æè¡ä¸ºè®¾ç½® |
| isolation | enum: Isolation | å¯éçäºå¡é离级å«è®¾ç½® |
| readOnly | boolean | 读åæåªè¯»äºå¡ï¼é»è®¤è¯»å |
| timeout | int (in seconds granularity) | äºå¡è¶ æ¶æ¶é´è®¾ç½® |
| rollbackFor | Class对象æ°ç»ï¼å¿ 须继æ¿èªThrowable | 导è´äºå¡åæ»çå¼å¸¸ç±»æ°ç» |
| rollbackForClassName | ç±»åæ°ç»ï¼å¿ 须继æ¿èªThrowable | 导è´äºå¡åæ»çå¼å¸¸ç±»ååæ°ç» |
| noRollbackFor | Class对象æ°ç»ï¼å¿ 须继æ¿èªThrowable | ä¸ä¼å¯¼è´äºå¡åæ»çå¼å¸¸ç±»æ°ç» |
| noRollbackForClassName | ç±»åæ°ç»ï¼å¿ 须继æ¿èªThrowable | ä¸ä¼å¯¼è´äºå¡åæ»çå¼å¸¸ç±»ååæ°ç» |
æåªäºäºå¡ä¼ æè¡ä¸ºï¼
å¨TransactionDefinitionæ¥å£ä¸å®ä¹äºä¸ä¸ªäºå¡ä¼ æè¡ä¸ºï¼
PROPAGATION_REQUIRED妿åå¨ä¸ä¸ªäºå¡ï¼åæ¯æå½åäºå¡ãå¦ææ²¡æäºå¡åå¼å¯ä¸ä¸ªæ°çäºå¡ã妿åµå¥è°ç¨çä¸¤ä¸ªæ¹æ³é½å äºäºå¡æ³¨è§£ï¼å¹¶ä¸è¿è¡å¨ç¸å线ç¨ä¸ï¼åè¿ä¸¤ä¸ªæ¹æ³ä½¿ç¨ç¸åçäºå¡ä¸ã妿è¿è¡å¨ä¸å线ç¨ä¸ï¼åä¼å¼å¯æ°çäºå¡ãPROPAGATION_SUPPORTS妿åå¨ä¸ä¸ªäºå¡ï¼æ¯æå½åäºå¡ãå¦ææ²¡æäºå¡ï¼åéäºå¡çæ§è¡ãPROPAGATION_MANDATORY妿已ç»åå¨ä¸ä¸ªäºå¡ï¼æ¯æå½åäºå¡ã妿ä¸åå¨äºå¡ï¼åæåºå¼å¸¸IllegalTransactionStateExceptionãPROPAGATION_REQUIRES_NEWæ»æ¯å¼å¯ä¸ä¸ªæ°çäºå¡ãéè¦ä½¿ç¨JtaTransactionManagerä½ä¸ºäºå¡ç®¡çå¨ãPROPAGATION_NOT_SUPPORTEDæ»æ¯éäºå¡å°æ§è¡ï¼å¹¶æèµ·ä»»ä½åå¨çäºå¡ãéè¦ä½¿ç¨JtaTransactionManagerä½ä¸ºäºå¡ç®¡çå¨ãPROPAGATION_NEVERæ»æ¯éäºå¡å°æ§è¡ï¼å¦æåå¨ä¸ä¸ªæ´»å¨äºå¡ï¼åæåºå¼å¸¸ãPROPAGATION_NESTED妿ä¸ä¸ªæ´»å¨çäºå¡åå¨ï¼åè¿è¡å¨ä¸ä¸ªåµå¥çäºå¡ä¸ãå¦ææ²¡ææ´»å¨äºå¡, åæPROPAGATION_REQUIRED 屿§æ§è¡ã
PROPAGATION_NESTED ä¸PROPAGATION_REQUIRES_NEWçåºå«:
使ç¨PROPAGATION_REQUIRES_NEWæ¶ï¼å
å±äºå¡ä¸å¤å±äºå¡æ¯ä¸¤ä¸ªç¬ç«çäºå¡ã䏿¦å
å±äºå¡è¿è¡äºæäº¤åï¼å¤å±äºå¡ä¸è½å¯¹å
¶è¿è¡åæ»ã两个äºå¡äºä¸å½±åã
使ç¨PROPAGATION_NESTEDæ¶ï¼å¤å±äºå¡çåæ»å¯ä»¥å¼èµ·å
å±äºå¡çåæ»ãèå
å±äºå¡çå¼å¸¸å¹¶ä¸ä¼å¯¼è´å¤å±äºå¡çåæ»ï¼å®æ¯ä¸ä¸ªçæ£çåµå¥äºå¡ã
Springäºå¡å¨ä»ä¹æ åµä¸ä¼å¤±æï¼
1.è®¿é®æéé®é¢
javaçè®¿é®æéä¸»è¦æåç§ï¼privateãdefaultãprotectedãpublicï¼å®ä»¬çæéä»å·¦å°å³ï¼ä¾æ¬¡å大ã
妿äºå¡æ¹æ³çè®¿é®æé䏿¯å®ä¹æpublicï¼è¿æ ·ä¼å¯¼è´äºå¡å¤±æï¼å 为springè¦æ±è¢«ä»£çæ¹æ³å¿
é¡»æ¯publicçã
ç¿»å¼æºç ï¼å¯ä»¥çå°ï¼å¨AbstractFallbackTransactionAttributeSourceç±»çcomputeTransactionAttributeæ¹æ³ä¸æä¸ªå¤æï¼å¦æç®æ æ¹æ³ä¸æ¯publicï¼åè¿ånullï¼å³ä¸æ¯æäºå¡ã
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
// Don't allow no-public methods as required.
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
...
}
2. æ¹æ³ç¨final修饰
妿äºå¡æ¹æ³ç¨final修饰ï¼å°ä¼å¯¼è´äºå¡å¤±æãå 为springäºå¡åºå±ä½¿ç¨äºaopï¼ä¹å°±æ¯éè¿jdk卿代çæè cglibï¼å¸®æä»¬çæäºä»£çç±»ï¼å¨ä»£çç±»ä¸å®ç°çäºå¡åè½ã
ä½å¦ææä¸ªæ¹æ³ç¨final修饰äºï¼é£ä¹å¨å®ç代çç±»ä¸ï¼å°±æ æ³éåè¯¥æ¹æ³ï¼èæ·»å äºå¡åè½ã
åçï¼å¦ææä¸ªæ¹æ³æ¯staticçï¼åæ ·æ æ³éè¿å¨æä»£çï¼åæäºå¡æ¹æ³ã
3.对象没æè¢«spring管ç
使ç¨springäºå¡çåææ¯ï¼å¯¹è±¡è¦è¢«spring管çï¼éè¦å建beanå®ä¾ãå¦æç±»æ²¡æå @Controllerã@Serviceã@Componentã@Repositoryçæ³¨è§£ï¼å³è¯¥ç±»æ²¡æäº¤ç»springå»ç®¡çï¼é£ä¹å®çæ¹æ³ä¹ä¸ä¼çæäºå¡ã
4.è¡¨ä¸æ¯æäºå¡
妿MySQL使ç¨çåå¨å¼ææ¯myisamï¼è¿æ ·çè¯æ¯ä¸æ¯æäºå¡çãå 为myisamåå¨å¼æä¸æ¯æäºå¡ã
5.æ¹æ³å é¨è°ç¨
å¦ä¸ä»£ç æç¤ºï¼updateæ¹æ³ä¸é¢æ²¡æå @Transactional 注解ï¼è°ç¨æ @Transactional 注解ç updateOrder æ¹æ³ï¼updateOrder æ¹æ³ä¸çäºå¡ä¼å¤±æã
å 为åçäºèªèº«è°ç¨ï¼è°ç¨è¯¥ç±»èªå·±çæ¹æ³ï¼è没æç»è¿ Spring ç代çç±»ï¼åªæå¨å¤é¨è°ç¨äºå¡æä¼çæã
@Service
public class OrderServiceImpl implements OrderService {
public void update(Order order) {
this.updateOrder(order);
}
@Transactional
public void updateOrder(Order order) {
// update order
}
}
è§£å³æ¹æ³ï¼
1ãå声æä¸ä¸ªserviceï¼å°å é¨è°ç¨æ¹ä¸ºå¤é¨è°ç¨
2ã使ç¨ç¼ç¨å¼äºå¡
3ã使ç¨AopContext.currentProxy()è·å代ç对象
@Servcie
public class OrderServiceImpl implements OrderService {
public void update(Order order) {
((OrderService)AopContext.currentProxy()).updateOrder(order);
}
@Transactional
public void updateOrder(Order order) {
// update order
}
}
6.æªå¼å¯äºå¡
妿æ¯spring项ç®ï¼åéè¦å¨é ç½®æä»¶ä¸æå¨é ç½®äºå¡ç¸å ³åæ°ã妿å¿äºé ç½®ï¼äºå¡è¯å®æ¯ä¸ä¼çæçã
妿æ¯springboot项ç®ï¼é£ä¹ä¸éè¦æå¨é
ç½®ãå 为springbootå·²ç»å¨DataSourceTransactionManagerAutoConfigurationç±»ä¸å¸®æä»¬å¼å¯äºäºå¡ã
7.åäºå¼å¸¸
ææ¶åäºå¡ä¸ä¼åæ»ï¼æå¯è½æ¯å¨ä»£ç 䏿å¨catchäºå¼å¸¸ãå 为å¼åè èªå·±æè·äºå¼å¸¸ï¼å没ææå¨æåºï¼æå¼å¸¸åæäºï¼è¿ç§æ åµä¸springäºå¡ä¸ä¼åæ»ã
妿æ³è¦springäºå¡è½å¤æ£å¸¸åæ»ï¼å¿ é¡»æåºå®è½å¤å¤ççå¼å¸¸ãå¦ææ²¡ææå¼å¸¸ï¼åspring认为ç¨åºæ¯æ£å¸¸çã
Springæä¹è§£å³å¾ªç¯ä¾èµçé®é¢ï¼
é¦å ï¼æä¸¤ç§Beanæ³¨å ¥çæ¹å¼ã
æé 卿³¨å ¥å屿§æ³¨å ¥ã
å¯¹äºæé 卿³¨å
¥ç循ç¯ä¾èµï¼Springå¤çä¸äºï¼ä¼ç´æ¥æåºBeanCurrentlylnCreationExceptionå¼å¸¸ã
对äºå±æ§æ³¨å ¥ç循ç¯ä¾èµï¼å便¨¡å¼ä¸ï¼ï¼æ¯éè¿ä¸çº§ç¼åå¤çæ¥å¾ªç¯ä¾èµçã
èéåä¾å¯¹è±¡ç循ç¯ä¾èµï¼åæ æ³å¤çã
ä¸é¢åæå便¨¡å¼ä¸å±æ§æ³¨å ¥ç循ç¯ä¾èµæ¯æä¹å¤ççï¼
é¦å ï¼Springåä¾å¯¹è±¡çåå§å大ç¥åä¸ºä¸æ¥ï¼
createBeanInstanceï¼å®ä¾åbeanï¼ä½¿ç¨æé æ¹æ³å建对象ï¼ä¸ºå¯¹è±¡åé å åãpopulateBeanï¼è¿è¡ä¾èµæ³¨å ¥ãinitializeBeanï¼åå§åbeanã
Spring为äºè§£å³åä¾ç循ç¯ä¾èµé®é¢ï¼ä½¿ç¨äºä¸çº§ç¼åï¼
singletonObjectsï¼å®æäºåå§åçåä¾å¯¹è±¡mapï¼bean name --> bean instance
earlySingletonObjects ï¼å®æå®ä¾åæªåå§åçåä¾å¯¹è±¡mapï¼bean name --> bean instance
singletonFactories ï¼ åä¾å¯¹è±¡å·¥åmapï¼bean name --> ObjectFactoryï¼åä¾å¯¹è±¡å®ä¾å宿ä¹åä¼å å
¥singletonFactoriesã
å¨è°ç¨createBeanInstanceè¿è¡å®ä¾åä¹åï¼ä¼è°ç¨addSingletonFactoryï¼å°åä¾å¯¹è±¡æ¾å°singletonFactoriesä¸ã
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
åå¦Aä¾èµäºBçå®ä¾å¯¹è±¡ï¼åæ¶Bä¹ä¾èµAçå®ä¾å¯¹è±¡ã
- Aé¦å 宿äºå®ä¾åï¼å¹¶ä¸å°èªå·±æ·»å å°singletonFactoriesä¸
- æ¥çè¿è¡ä¾èµæ³¨å ¥ï¼åç°èªå·±ä¾èµå¯¹è±¡Bï¼æ¤æ¶å°±å°è¯å»get(B)
- åç°Bè¿æ²¡æè¢«å®ä¾åï¼å¯¹Bè¿è¡å®ä¾å
- ç¶åBå¨åå§åçæ¶ååç°èªå·±ä¾èµäºå¯¹è±¡Aï¼äºæ¯å°è¯get(A)ï¼å°è¯ä¸çº§ç¼åsingletonObjectsåäºçº§ç¼åearlySingletonObjects没æ¾å°ï¼å°è¯ä¸çº§ç¼åsingletonFactoriesï¼ç±äºAåå§åæ¶å°èªå·±æ·»å å°äºsingletonFactoriesï¼æä»¥Bå¯ä»¥æ¿å°A对象ï¼ç¶åå°Aä»ä¸çº§ç¼åä¸ç§»å°äºçº§ç¼åä¸
- Bæ¿å°A对象å顺å©å®æäºåå§åï¼ç¶åå°èªå·±æ¾å ¥å°ä¸çº§ç¼åsingletonObjectsä¸
- æ¤æ¶è¿åAä¸ï¼Aæ¤æ¶è½æ¿å°Bç对象顺å©å®æèªå·±çåå§å
ç±æ¤çåºï¼å±æ§æ³¨å ¥ç循ç¯ä¾èµä¸»è¦æ¯éè¿å°å®ä¾å宿çbeanæ·»å å°singletonFactoriesæ¥å®ç°çãèä½¿ç¨æé å¨ä¾èµæ³¨å ¥çbeanå¨å®ä¾åçæ¶åä¼è¿è¡ä¾èµæ³¨å ¥ï¼ä¸ä¼è¢«æ·»å å°singletonFactoriesä¸ãæ¯å¦AåB齿¯éè¿æé å¨ä¾èµæ³¨å ¥ï¼Aå¨è°ç¨æé å¨è¿è¡å®ä¾åçæ¶åï¼åç°èªå·±ä¾èµBï¼B没æè¢«å®ä¾åï¼å°±ä¼å¯¹Bè¿è¡å®ä¾åï¼æ¤æ¶Aæªå®ä¾å宿ï¼ä¸ä¼è¢«æ·»å å°singtonFactoriesãèBä¾èµäºAï¼Bä¼å»ä¸çº§ç¼å寻æ¾A对象ï¼åç°ä¸åå¨ï¼äºæ¯åä¼å®ä¾åAï¼Aå®ä¾åäºä¸¤æ¬¡ï¼ä»èå¯¼è´æå¼å¸¸ã
æ»ç»ï¼1ãå©ç¨ç¼åè¯å«å·²ç»éåè¿çèç¹ï¼ 2ãå©ç¨Javaå¼ç¨ï¼å æå设置对象å°åï¼åå®å对象ã
Springå¯å¨è¿ç¨
读åweb.xmlæä»¶ã
å建 ServletContextï¼ä¸º ioc 容卿ä¾å®¿ä¸»ç¯å¢ã
触å容å¨åå§åäºä»¶ï¼è°ç¨ contextLoaderListener.contextInitialized()æ¹æ³ï¼å¨è¿ä¸ªæ¹æ³ä¼åå§åä¸ä¸ªåºç¨ä¸ä¸æWebApplicationContextï¼å³ Spring ç ioc 容å¨ãioc 容å¨åå§å宿ä¹åï¼ä¼è¢«åå¨å° ServletContext ä¸ã
åå§åweb.xmlä¸é ç½®çServletãå¦DispatcherServletï¼ç¨äºå¹é ãå¤çæ¯ä¸ªservlet请æ±ã
Spring çåä¾ Bean æ¯å¦æå¹¶åå®å ¨é®é¢ï¼
å½å¤ä¸ªç¨æ·åæ¶è¯·æ±ä¸ä¸ªæå¡æ¶ï¼å®¹å¨ä¼ç»æ¯ä¸ä¸ªè¯·æ±åé ä¸ä¸ªçº¿ç¨ï¼è¿æ¶å¤ä¸ªçº¿ç¨ä¼å¹¶åæ§è¡è¯¥è¯·æ±å¯¹åºçä¸å¡é»è¾ï¼å¦æä¸å¡é»è¾æå¯¹åä¾ç¶æçä¿®æ¹ï¼ä½ç°ä¸ºæ¤åä¾çæå屿§ï¼ï¼åå¿ é¡»èè线ç¨å®å ¨é®é¢ã
æ ç¶æbeanåæç¶æbean
- æå®ä¾åéçbeanï¼å¯ä»¥ä¿åæ°æ®ï¼æ¯é线ç¨å®å ¨çã
- 没æå®ä¾åéçbeanï¼ä¸è½ä¿åæ°æ®ï¼æ¯çº¿ç¨å®å ¨çã
å¨Spring䏿 ç¶æçBeanéåç¨å便¨¡å¼ï¼è¿æ ·å¯ä»¥å
±äº«å®ä¾æé«æ§è½ãæç¶æçBeanå¨å¤çº¿ç¨ç¯å¢ä¸ä¸å®å
¨ï¼ä¸è¬ç¨Prototypeæ¨¡å¼æè
使ç¨ThreadLocalè§£å³çº¿ç¨å®å
¨é®é¢ã
Spring Beanå¦ä½ä¿è¯å¹¶åå®å ¨ï¼
SpringçBeané»è®¤é½æ¯åä¾çï¼æäºæ åµä¸ï¼å便¯å¹¶åä¸å®å ¨çã
以 Controller 举ä¾ï¼åå¦æä»¬å¨ Controller ä¸å®ä¹äºæååéãå½å¤ä¸ªè¯·æ±æ¥ä¸´ï¼è¿å
¥ç齿¯åä¸ä¸ªåä¾ç Controller 对象ï¼å¹¶å¯¹æ¤æååéçå¼è¿è¡ä¿®æ¹æä½ï¼å æ¤ä¼äºç¸å½±åï¼ä¼æå¹¶åå®å
¨çé®é¢ã
åºè¯¥æä¹è§£å³å¢ï¼
为äºè®©å¤ä¸ªHTTP请æ±ä¹é´ä¸äºç¸å½±åï¼å¯ä»¥éå以䏿ªæ½ï¼
1ãåä¾ååå
对 web 项ç®ï¼å¯ä»¥ Controller ç±»ä¸å 注解 @Scope("prototype") æ @Scope("request")ï¼å¯¹é web 项ç®ï¼å¨ Component ç±»ä¸æ·»å 注解 @Scope("prototype") ã
è¿ç§æ¹å¼å®ç°èµ·æ¥é常ç®åï¼ä½æ¯å¾å¤§ç¨åº¦ä¸å¢å¤§äº Bean å建å®ä¾å鿝çæå¡å¨èµæºå¼éã
2ãå°½éé¿å ä½¿ç¨æååé
å¨ä¸å¡å è®¸çæ¡ä»¶ä¸ï¼å¯ä»¥å°æååéæ¿æ¢ä¸ºæ¹æ³ä¸çå±é¨åéãè¿ç§æ¹å¼ä¸ªäººè®¤ä¸ºæ¯ææ°å½çã
3ã使ç¨å¹¶åå®å ¨çç±»
妿éè¦å¨åä¾Beanä¸ä½¿ç¨æååéï¼å¯ä»¥èè使ç¨å¹¶åå®å
¨ç容å¨ï¼å¦ ConcurrentHashMapãConcurrentHashSet ççï¼å°æä»¬çæååéå
è£
å°è¿äºå¹¶åå®å
¨ç容å¨ä¸è¿è¡ç®¡çå³å¯ã
4ãåå¸å¼æå¾®æå¡çå¹¶åå®å ¨
妿è¿è¦è¿ä¸æ¥èèå°å¾®æå¡æåå¸å¼æå¡çå½±åï¼æ¹å¼3便ä¸åéäºãè¿ç§æ åµä¸å¯ä»¥åå©äºå¯ä»¥å ±äº«æäºä¿¡æ¯çåå¸å¼ç¼åä¸é´ä»¶ï¼å¦Redisçãè¿æ ·å³å¯ä¿è¯åä¸ç§æå¡çä¸åæå¡å®ä¾é½æ¥æåä¸ä»½å ±äº«ä¿¡æ¯äºã
@Async注解çåç
彿们è°ç¨ç¬¬ä¸æ¹æ¥å£æè æ¹æ³çæ¶åï¼æä»¬ä¸éè¦çå¾ æ¹æ³è¿åæå»æ§è¡å ¶å®é»è¾ï¼è¿æ¶å¦æååºæ¶é´è¿é¿ï¼å°±ä¼æå¤§çå½±åç¨åºçæ§è¡æçãæä»¥è¿æ¶å°±éè¦ä½¿ç¨å¼æ¥æ¹æ³æ¥å¹¶è¡æ§è¡æä»¬çé»è¾ãå¨springbootä¸å¯ä»¥ä½¿ç¨@Async注解å®ç°å¼æ¥æä½ã
使ç¨@Async注解å®ç°å¼æ¥æä½çæ¥éª¤ï¼
1.é¦å å¨å¯å¨ç±»ä¸æ·»å @EnableAsync 注解ã
@Configuration
@EnableAsync
public class App {
public static void main(String[] args) {
ApplicationContext ctx = new
AnnotationConfigApplicationContext(App.class);
MyAsync service = ctx.getBean(MyAsync.class);
System.out.println(service.getClass());
service.async1();
System.out.println("main thread finish...");
}
}
2.å¨å¯¹åºçæ¹æ³ä¸æ·»å @Async注解ã
@Component
public class MyAsync {
@Async
public void asyncTest() {
try {
TimeUnit.SECONDS.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("asyncTest...");
}
}
è¿è¡ä»£ç ï¼æ§å¶å°è¾åºï¼
main thread finish...
asyncTest...
è¯æasyncTestæ¹æ³å¼æ¥æ§è¡äºã
åçï¼
æä»¬å¨ä¸»å¯å¨ç±»ä¸è´´äºä¸ä¸ª@EnableAsyncæ³¨è§£ï¼æè½ä½¿ç¨@Asyncçæã@EnableAsyncçä½ç¨æ¯éè¿@importå¯¼å ¥äºAsyncConfigurationSelectorãå¨AsyncConfigurationSelectorçselectImportsæ¹æ³å°ProxyAsyncConfigurationå®ä¹ä¸ºBeanæ³¨å ¥å®¹å¨ãå¨ProxyAsyncConfigurationä¸éè¿@Beançæ¹å¼æ³¨å ¥AsyncAnnotationBeanPostProcessorç±»ã

代ç å¦ä¸ï¼
@Import(AsyncConfigurationSelector.class)
public @interface EnableAsync {
}
public class AsyncConfigurationSelector extends AdviceModeImportSelector<EnableAsync> {
public String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
return new String[] { ProxyAsyncConfiguration.class.getName() };
//...
}
}
}
public class ProxyAsyncConfiguration extends AbstractAsyncConfiguration {
@Bean(name = TaskManagementConfigUtils.ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME)
public AsyncAnnotationBeanPostProcessor asyncAdvisor() {
//å建postProcessor
AsyncAnnotationBeanPostProcessor bpp = new AsyncAnnotationBeanPostProcessor();
//...
}
}
AsyncAnnotationBeanPostProcessorå¾å¾æå建äºä¸ä¸ªå¢å¼ºå¨AsyncAnnotationAdvisorãå¨AsyncAnnotationAdvisorçbuildAdviceæ¹æ³ä¸ï¼å建äºAnnotationAsyncExecutionInterceptorã
public class AsyncAnnotationBeanPostProcessor extends AbstractBeanFactoryAwareAdvisingPostProcessor {
@Override
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
//å建ä¸ä¸ªå¢å¼ºå¨
AsyncAnnotationAdvisor advisor = new AsyncAnnotationAdvisor(this.executor, this.exceptionHandler);
//...
advisor.setBeanFactory(beanFactory);
this.advisor = advisor;
}
}
public class AsyncAnnotationAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware {
public AsyncAnnotationAdvisor(
@Nullable Supplier<Executor> executor, @Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler) {
//å¢å¼ºæ¹æ³
this.advice = buildAdvice(executor, exceptionHandler);
this.pointcut = buildPointcut(asyncAnnotationTypes);
}
// å§æç»AnnotationAsyncExecutionInterceptoræ¦æªå¨
protected Advice buildAdvice(
@Nullable Supplier<Executor> executor, @Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler) {
//æ¦æªå¨
AnnotationAsyncExecutionInterceptor interceptor = new AnnotationAsyncExecutionInterceptor(null);
interceptor.configure(executor, exceptionHandler);
return interceptor;
}
}
AnnotationAsyncExecutionInterceptorç»§æ¿èªAsyncExecutionInterceptorï¼é´æ¥å®ç°äºMethodInterceptorãè¯¥æ¦æªå¨çå®ç°çinvokeæ¹æ³æåæ¥æ¹æ³çè°ç¨æäº¤å°æ°ççº¿ç¨æ± æ§è¡ï¼ä»èå®ç°äºæ¹æ³ç弿¥ã
public class AsyncExecutionInterceptor extends AsyncExecutionAspectSupport implements MethodInterceptor, Ordered {
public Object invoke(final MethodInvocation invocation) throws Throwable {
//...
//æå»ºæ¾å°AsyncTaskExecutoræ§è¡Callable Task
Callable<Object> task = () -> {
//...
};
//æäº¤å°æ°ççº¿ç¨æ± æ§è¡
return doSubmit(task, executor, invocation.getMethod().getReturnType());
}
}
ç±ä¸é¢åæå¯ä»¥çå°ï¼@Asyncæ³¨è§£å ¶å®æ¯éè¿ä»£ççæ¹å¼æ¥å®ç°å¼æ¥è°ç¨çã
é£ä½¿ç¨@Asyncæä»ä¹è¦æ³¨æçå¢ï¼
1.使ç¨@Aysncçæ¶åæå¥½é ç½®ä¸ä¸ªçº¿ç¨æ± Executor以让线ç¨å¤ç¨èçèµæºï¼æè 为SimpleAsyncTaskExecutor设置åºäºçº¿ç¨æ± å®ç°çThreadFactoryï¼å¨å¦åä¼é»è®¤ä½¿ç¨SimpleAsyncTaskExecutorï¼è¯¥executorä¼å¨æ¯æ¬¡è°ç¨æ¶æ°å»ºä¸ä¸ªçº¿ç¨ã
2.è°ç¨æ¬ç±»ç弿¥æ¹æ³æ¯ä¸ä¼èµ·ä½ç¨çãè¿ç§æ¹å¼ç»è¿äºä»£çèç´æ¥è°ç¨äºæ¹æ³ï¼@Async注解ä¼å¤±æã
为ä»ä¹ SpringåIDEA é½ä¸æ¨èä½¿ç¨ @Autowired 注解ï¼
idea 卿们ç»å¸¸ä½¿ç¨ç@Autowired æ³¨è§£ä¸æ·»å äºè¦åãè¦åå
容æ¯: Field injection is not recommended, è¯ä¸º: 䏿¨è使ç¨å±æ§æ³¨å
¥ã
Spring常ç¨çæ³¨å ¥æ¹å¼æï¼å±æ§æ³¨å ¥, æé æ¹æ³æ³¨å ¥, set æ¹æ³æ³¨å ¥
- æé 卿³¨å ¥ï¼å©ç¨æé æ¹æ³çåæ°æ³¨å ¥ä¾èµ
- setæ¹æ³æ³¨å ¥ï¼è°ç¨setterçæ¹æ³æ³¨å ¥ä¾èµ
- 屿§æ³¨å ¥ï¼å¨å段ä¸ä½¿ç¨@Autowired/Resource注解
å ¶ä¸ï¼åºäºå±æ§æ³¨å ¥çæ¹å¼ï¼å®¹æå¯¼è´Spring åå§å失败ãå 为å¨Springå¨åå§åçæ¶åï¼å¯è½ç±äºå±æ§å¨è¢«æ³¨å ¥åå°±å¼ç¨è导è´ç©ºæéå¼å¸¸ï¼è¿è导è´å®¹å¨åå§å失败ã
妿å¯è½çè¯ï¼å°½éä½¿ç¨æé 卿³¨å
¥ãLombokæä¾äºä¸ä¸ªæ³¨è§£@RequiredArgsConstructor, å¯ä»¥æ¹ä¾¿æä»¬å¿«éè¿è¡æé 注å
¥ã
@Autowiredæ¯å±æ§æ³¨å ¥ï¼èä¸@Autowiredé»è®¤æ¯æç §ç±»åå¹é ï¼ByTypeï¼ï¼å æ¤æå¯è½ä¼åºç°ä¸¤ä¸ªç¸åçç±»åbeanï¼è¿è导è´Spring è£ é 失败ã
妿è¦ä½¿ç¨å±æ§æ³¨å
¥çè¯ï¼å¯ä»¥ä½¿ç¨ @Resource ä»£æ¿ @Autowired 注解ã@Resourceé»è®¤æ¯æç
§åç§°å¹é
ï¼ByNameï¼ï¼å¦ææ¾ä¸å°åæ¯ByType注å
¥ãå¦å¤ï¼@Autowiredæ¯Springæä¾çï¼@Resourceæ¯JSR-250æä¾çï¼æ¯Javaæ åï¼æä»¬ä½¿ç¨çIoC容å¨ä¼å»å
¼å®¹å®ï¼è¿æ ·å³ä½¿æ´æ¢å®¹å¨ï¼ä¹å¯ä»¥æ£å¸¸å·¥ä½ã
æåç»å¤§å®¶å享200夿¬è®¡ç®æºç»å ¸ä¹¦ç±PDFçµå书ï¼å æ¬Cè¯è¨ãC++ãJavaãPythonãåç«¯ãæ°æ®åºãæä½ç³»ç»ãè®¡ç®æºç½ç»ãæ°æ®ç»æåç®æ³ãæºå¨å¦ä¹ ãç¼ç¨äººççï¼æå ´è¶£çå°ä¼ä¼´å¯ä»¥èªåï¼
200夿¬è®¡ç®æºç»å ¸ä¹¦ç±PDFçµå书ï¼https://mp.weixin.qq.com/s/3udLZjoVTdqAcp3jJ0MRGQ




