springmvc源碼深度解析之攔截器過濾器視圖層分析_第1頁
springmvc源碼深度解析之攔截器過濾器視圖層分析_第2頁
springmvc源碼深度解析之攔截器過濾器視圖層分析_第3頁
springmvc源碼深度解析之攔截器過濾器視圖層分析_第4頁
springmvc源碼深度解析之攔截器過濾器視圖層分析_第5頁
已閱讀5頁,還剩34頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

Spring5.0源碼深度解析課程安Spring5.0事務源碼分Spring5.0AopSpring5.0、SpringMVCSpringBoot2.0余老 Spring框架快速入什么Spring框SpringJavaIoC(InversionofControlAOP(AspectOrientedProgramming,面NewUserService();Spring體系結1、SpringCore:BeanFactoryJavaBean(IOC)模式將應用程序的配置和依賴性規(guī)范與實際的應用程序代碼分開。2、SpringAOP:集成了面向切面的編程功能(AOP可以將性事物管理集成到應用程序中。3、SpringCntext:一個配置文件,為Spring框架提供上下文信息4、SpringDo:Spring5、SpringORM:Spring集成了各種orm(objectrelationshipmap對象關系映射6、SpringWebweb(Struts、7、SpringwebMVC:Springweb思考一個問題為什么啟動SpringBoot項目的時候需要加上Configuration快速構建Spring環(huán)Maven依賴信<artifactId>spring-Xml方式環(huán)境搭<beanid="userEntity"<beanid="userEntity"<propertyname="userId"<propertyname="userName"<beans" " " bean對publicclasspublicclassUserEntity{privateIntegeruserId;privateStringuserName;publicUserEntity(IntegeruserId,StringuserName)this.userId=this.userName=}publicvoidsetUserId(IntegeruserId)this.userId=}publicvoidsetUserName(StringuserName)this.userName=}publicStringtoString()return"UserEntity{""userId="+userId",userName='"+userName+'\''}}Spring啟動 spring配置文件,IOC容ClassPathXmlApplicationContextclassPath=new//UserEntityuserEntity=(UserEntity)classPath.getBean("userEntity");注解方式環(huán)境搭Configuration配置容publicpublicclassMySpringConfig//@Configuration等同于配置的spring配置文publicUserEntityuserEntity()returnnewUserEntity(10,}}publicclassUserEntity{privateIntegeruserId;privateStringuserName;publicUserEntity(IntegeruserId,StringuserName)this.userId=this.userName=}publicIntegergetUserId()return}publicStringgetUserName()return}publicvoidsetUserId(IntegeruserId)this.userId=}publicpublicvoidsetUserName(StringuserName)this.userName=}}使用注解形式形式加載privateprivatestaticAnnotationConfigApplicationContextpublicstaticvoidmain(String[]args)applicationContext=newAnnotationConfigApplicationContext(MySpringConfig.class);UserEntityuserEntity=applicationContext.getBean("userEntity",UserEntity.class);}@ComponentScan用掃包下注入springIOC容器publicclassMySpringConfig{//@Configuration等同于配spring配置文publicUserEntityuserEntity()returnnewUserEntity(10,}}privateprivatestaticAnnotationConfigApplicationContextpublicstaticvoidmain(String[]args)annotationConfigApplicationContextannotationConfigApplicationContext=newAnnotationConfigApplicationContext(MySpringConfig.class);UserServiceuserService=annotationConfigApplicationContext.getBean("userService",UserService.class);System.out.println("userService:"+userService);System.out.println("以下為IOC容器注入成功的對象String[]beanDefinitionNames=for(inti=0;i<beanDefinitionNames.length;i++){}}FilterType有四種類型ASPECTJAspectj@ComponentScan(value@ComponentScan(value="com.mayikt.v2",includeFilters={@ComponentScan.Filter(type=FilterType.ANNOTATION,=Controller.class)},useDefaultFilters=false)publicclassMySpringConfig{//@Configuration等同于配spring配置文publicUserEntityuserEntity()returnnewUserEntity(10,}}@ComponentScan(value@ComponentScan(value="com.mayikt.v2",excludeFilters={@ComponentScan.Filter(type=FilterType.ANNOTATION,=Controller.class)},useDefaultFilters=true)publicclassMySpringConfig{//@Configuration等同于配spring配置文publicUserEntityuserEntity()returnnewUserEntity(10,}}}SpringsingletonprototypeBeanrequestBeanBeanHttp請session作用域表示煤氣請求都會產生一個新的BeanBean僅在當前HttpUserServiceUserServiceuserService1=annotationConfigApplicationContext.getBean("userService",UserServiceuserService2=annotationConfigApplicationContext.getBean("userService",結果為Lazy表示為懶加載,當真正需要獲取的時候才會被加True表示為懶加載false表示為在IOC容器加載的時候被創(chuàng)建publicclassUserServicepublicUserService()System.out.println("UserService無參數構造被加載}}}Condition是在spring4.0增加的條件注解,通過這個可以功能可以實現選擇性的注入Bean操作,接下來先學習下Condition是如何使用的,然后分析spring源碼了解其中的實SpringWIN7win7publicpublicclassMyConditionimplementsCondition根據條件判斷上下文*@param@parampublicbooleanmatches(ConditionContextcontext,AnnotatedTypeMetadatametadata)1.獲取當前環(huán)境配Environmentenvironment=context.getEnvironment();StringosName=environment.getProperty("");if(osName.equals("Windows7")){true就是能夠創(chuàng)建該return}return}}publicWin7Entitywin7Entity(){returnnew}@Import注@Import@Configurationbean@Import({V5UserEntity.class,默 beanid@Import({V5UserEntity.class,publicpublicclassMyImportSelectorimplementsImportSelectorAnnotationMetadata注解信*@param//添加需 的spring容器的returnnew}}@public@interfaceEnableUser}publicclassMyImportBeanDefinitionRegistrarimplementspublicclassMyImportBeanDefinitionRegistrarimplementsImportBeanDefinitionRegistrarpublicpublicvoidregisterBeanDefinitions(AnnotationMetadataimportingClassMetadata,BeanDefinitionRegistryregistry)//手 StringbeanName=RootBeanDefinitionrootBeanDefinition=newRootBeanDefinition(PayEntity.class);registry.registerBeanDefinition(beanName,rootBeanDefinition);}}publicpublicclassMyFactoryBeanimplementsFactoryBean<MemberEntity>publicMemberEntitygetObject()throwsExceptionreturnnew}publicClass<?>getObjectType()return}publicbooleanisSingleton()return}}publicMyFactoryBeanmyFactoryBean()returnnew}區(qū)別:BeanFactory是個Factory,也就是IOC容器或對象工廠,FactoryBean是個Bean。SpringBeanBeanFactoryIOCFactoryBean而言,這個Bean不是簡單的Bean,而是一個能生產或者修飾對象生成的工廠SpringBean的生命周期總refresh();getBean()→doGetBean()→createBean()→doCreateBean()→createBeanInstance(初始化對JavaCGLIBinvokeAwareMethods()awareapplyBeanPostProcessorsAfterInitializationSpringAop源碼分AspectJAutoProxyRegistrar中會對象BeanClass:AnnotationAwareAspectJAutoProxyCreatorAutoProxyCreator有是 AutoProxyCreator經過這樣的一個類。判斷該被對象是否有被有實現過接口,如果有實現過接口就使用jdk動態(tài),如果沒有實現接口則使用cglib動態(tài)。MethodInterceptor(每個通知)invoke模擬SpringAop五個通知調用鏈關UserService接publicpublicclassUserServicepublicvoidlogin(StringuserName,Stringage){System.out.println("userName:"+userName+",age:"+age);}}創(chuàng)建方法接publicpublicinterfaceMethodInterceptor執(zhí)行通知*@paramObjectinvoke(MethodInvocationmethodInvocation)throwsInvocationTargetException,}創(chuàng)建前置通publicpublicclassBeforMethodInterceptorimplementsMethodInterceptorpublicObjectinvoke(MethodInvocationmethodInvocationthrowsInvocationTargetExceptionIllegalAccessExceptionreturnmethodIcess();//目標方}}創(chuàng)建后置通publicpublicclassAfterMethodInterceptorimplementsMethodInterceptorpublicObjectinvoke(MethodInvocationmethodInvocation)InvocationTargetException,IllegalAccessExceptionObjectprocessmethodIcess();return}}創(chuàng)建環(huán)繞通publicpublicclassAroundMethodInterceptorimplementsMethodInterceptorpublicObjectinvoke(MethodInvocationmethodInvocation)throwsInvocationTargetException,IllegalAccessException{ Objectprocess=System.out.println("環(huán)繞通知之后執(zhí) return}}創(chuàng)建方法執(zhí)行接publicpublicinterfaceMethodInvocation方法調用個通知的方*Objectprocess()throwsInvocationTargetException,}publicclassDefaultMethodInvacationimplementsMethodInvocationprivateList<MethodInterceptor>chian;privateObjecttarget;//目標對象privateMethodmethod;//目標方法privateObjectargs[];//目標參數publicDefaultMethodInvacation(List<MethodInterceptor>chian,Objecttarget,Methodmethod,Object[]args)this.chian=chian;this.target=target;this.method=method;this.args=args;}publicObjectprocess()throwsInvocationTargetException,IllegalAccessExceptionif(currentChianIndex==chian.size())執(zhí)行目標returnreturnmethod.invoke(target,}MethodInterceptormethodInterceptor=//return}}Spring事務底層源碼分SpringAop基本環(huán)境搭Maven依賴信<artifactId>spring-mysql<artifactId>mysql-connector-<artifactId>spring-publicclassMyConfig{publicDataSourcedataSource()MysqlDataSourcemysqlDataSource=newMysqlDataSource();return}publicJdbcTemplatejdbcTemplate()returnnew}publicPlatformTransactionManagertxManager()returnnew}}publicclassOrderDao{privateJdbcTemplatepublicvoidaddOrderInfo()jdbcTemplate.update("insertintoorder_info}}Spring事務源碼分Aop實現一樣的功能。Ioc容器中TransactionInterceptor是 ifif(txAttr==null||!(tminstanceofCallbackPreferringPlatformTransactionManager))開啟事TransactionInfotxInfo=createTransactionIfNecessary(tm,txAttr,joinpointIdentification);ObjectretVal=null;try執(zhí)行目標方retVal=}catch(Throwableex)//回滾當前事務completeTransactionAfterThrowing(txInfo,ex);throwex;}finally}returnretVal;}純手寫SpringAop環(huán)繞通知+手動事務就可以事SpringAop中所有最終是如何執(zhí)行?調用鏈關AutoProxyCreator使用該類創(chuàng)建目標對象(TransactionInterceptor事務@EnableTransactionManagementePROXY: Beanid:Value:ProxyTransactionManagementConfiguration將一下對象到ioc容Value:tansactionInterceptorInfrastructureAdvisorAutoProxyCreator就是我們的后置處理Bean對象在初始化之后都會判斷是否需要創(chuàng)建類(根據是否有加上InfrastructureAdvisorAutoProxyCreator就 serviceSpring循環(huán)依賴原什么Spring循環(huán)依賴問如何解決Spring循環(huán)依賴相關業(yè)務邏輯代publicclassAService{ privateBServicepublicvoidsetbService(BServicebService)this.bService=}}publicclassBService{ privateAServicepublicvoidsetaService(AServiceaService)this.aService=}}如何底層解決循環(huán)依賴原循環(huán)依賴中完整對象信Map<String,Object>singletonObjects一級緩存完成對象(對象和屬性都已經賦值)Map<String,Object>earlySingletonObjects性缺沒有賦值早期對象Map<String,ObjectFactory<?>>singletonFactories三級緩存(只初始化,沒有給屬性賦值對象)存放提前對象AB依賴與BBAASpringBeanA(單例的情況doGetBeanStringbeanNameStringbeanNameObjectFactory<?>singletonFactorycreateBean→doCreateBeancreateBeanInstancecglib(注意對象不完整,因為熟悉沒有duGetBean1-6BAgetSingletonAapplyPropertyValues→valueResolver.resolveValueIfNecessary→resolveReference(argName,ref)init(初始化HashMap<Object,HashMap<Object,Object>objectHashMap=newHashMap<Object,1.A對objectHashMap.put("aService",new//2.B對象從三級緩存中查找到objectHashMap.put("bService",newAServiceaService=(AService)objectHashMap.get("aService");BServicebService=(BService)objectHashMap.get("bService");bService.aService=aService;//3.A對象需要設aService.bService=protectedprotectedObjectgetSingleton(StringbeanName,booleanallowEarlyReference)1.ObjectsingletonObject=//2.沒有創(chuàng)建對象,并且該對象正在創(chuàng)建(標記為循環(huán)依賴的查詢if(singletonObject==null&&isSingletonCurrentlyInCreation(beanName))//3.singletonObject=this.earlySingletonObjects.get(beanName);if(singletonObject==null&&allowEarlyReference){//4.ObjectFactory<?>singletonFactory=this.singletonFactories.get(beanName);if(singletonFactory!=null){singletonObject=singletonFactory.getObject();this.earlySingletonObjects.put(beanName,singletonObject);}}}}returnprotectedprotectedvoidaddSingletonFactory(StringbeanName,ObjectFactory<?>singletonFactory){Assert.notNull(singletonFactory,"Singletonfactorymustnotbenull");if(!this.singletonObjects.containsKey(beanName)){this.singletonFactories.put(beanName,singletonFactory);}}},BAABBAbeaniscurrentlyincreation:IsthereanunresolvablecircularABBABBABABAABSpringBean創(chuàng)建AdoGetBeangetSingleton(StringgetSingleton(StringbeanName,ObjectFactory<?>singletonFactory)this.singletonsCurrentlyInCreation.add(beanName)createBeanInstancecglibbeanaddSingletonFactorypopulateBeanABBBAprotectedvoidaddSingleton(StringbeanName,ObjectsingletonObject){synchronized(this.singletonObjects){this.singletonObjects.put(beanName,publicObjectprotectedprotectedvoidaddSingletonFactory(StringbeanName,ObjectFactory<?>singletonFactory){Assert.notNull(singletonFactory,"Singletonfactorymustnotbenull");//判斷一級緩存是否存if(!this.singletonObjects.containsKey(beanName))//將該不完整的對象存放到三級緩存集合中this.singletonFactories.put(beanName,singletonFactory);}}}protectedprotectedObjectgetSingleton(StringbeanName,booleanallowEarlyReference)//1.一級緩存bean對象該集合緩存的對象為完整對象對象創(chuàng)建完畢并且已經屬性賦值成功ObjectsingletonObject=if(singletonObject==null&&isSingletonCurrentlyInCreation(beanName))//2.從二級緩存中獲取對象信singletonObject=this.earlySingletonObjects.get(beanName);if(singletonObject==null&&allowEarlyReference){3.從三級緩存中獲取對ObjectFactory<?>singletonFactory=this.singletonFactories.get(beanName);if(singletonFactory!=null){singletonObjectsingletonObject=//4.如果三級緩存中存在對象的時候下,就返回二級緩存中。this.earlySingletonObjects.put(beanName,singletonObject);}}}}return}SpringIOCAOP依賴注入賦值ABB對象BAAspringSpringBeanAservicgetSingleton(beanName)singletonObjects一級緩存完整對象earlySingletonObjectssingletonFactories三級緩存存放嬰兒對象嬰兒對象(提前對象){}singletonsCurrentlyInCreationgetSingleton(StringbeanName,ObjectFactory<?>singletonFactory)this.singletonsCurrentlyInCreation.add(beanName)表示該對象已經開始創(chuàng)建createBean() 賦值的)存放三級緩存中。ABABBprotectedprotectedvoidaddSingletonFactory(StringbeanName,ObjectFactory<?>singletonFactory){Assert.notNull(singletonFactory,"Singletonfactorymustnotbenull");//如果一級緩存沒有該對象的情if(!this.singletonObjects.containsKey(beanName))//將該對象存放到三級緩存中嬰兒對象this.singletonFactories.put(beanName,singletonFactory);}}}protectedprotectedObjectgetSingleton(StringbeanName,booleanallowEarlyReference)//1.一級緩存對象集合(緩存完整對象)對象已經創(chuàng)建成功呢并且所有的屬性都已經賦值成ObjectsingletonObject=2.如果已經緩存沒if(singletonObject==null&&isSingletonCurrentlyInCreation(beanName))//查詢二級緩存是否有緩存對singletonObject=this.earlySingletonObjects.get(beanName);if(singletonObject==null&&allowEarlyReference){//4.查詢三級緩存,三級緩存如果有的情況ObjectFactory<?>singletonFactory=this.singletonFactories.get(beanName);if(singletonFactory!=null){singletonObject=//將三級緩存中的數據放入到二級緩存中this.earlySingletonObjects.put(beanName,singletonObject);}}}}return}SpringMVC源碼分Servlet開發(fā)基本環(huán)Servlet簡單的介SunAPIservletwebJava2ServletServletSpringMVC關idea快速創(chuàng)建一個Servlet項創(chuàng)建的mavenweb工廠發(fā)現沒有 ,則創(chuàng)建XML方 publicclassMyServletextendsHttpServletprotectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)ServletException,IOException{resp.getWriter().print("thisismayikt");}}基于注解方publicclassMyServletextendsHttpServletprotectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)ServletException,IOException{resp.getWriter().print("thisismayikt");}}Servlet線程是否答案:不安全,Servlet是單例的在高并況下,可能會存程安全問publicclassMyServletextendsHttpServletprivateIntegercount=publicMyServlet(){}protectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOExceptiontry{}catch(Exceptione)}resp.getWriter().print("thisismayiktcount:"+}}在web容器啟動時為提供給第組件機會做一些初始化的工作,例如servlet或filtes等,servletServletContainerInitializer每個框架要使用ServletContainerInitializer就必須在對應的jar包的META-INF/services 建一個名為javax.servlet.ServletContainerInitializer的文件,文件內容指定具體的ServletContainerInitializer實現類。1、Servlet容器掃描,當前應用里面每一個jar包ServletContainerInitializer2ServletContainerInitializerServletContainerInitializer實現類的全類名;相關代@author螞蟻課堂創(chuàng)始人@title:@description:每特教育獨創(chuàng)第五期互聯網架構課@date@HandlesTypes(value=publicclassMyServletContainerInitializerimplementsServletContainerInitializer*@param 類型也就是MyHandlesType所有子類@param@throwspublicvoidonStartup(Set<Class<?>>set,ServletContextservletContext)throwsServletException//1.打印所有 的類forfor(Class<?>c:set){}//2.servletContext手動過濾器 ServletRegistration.DynamicpayServlet=servletContext.addServlet("payServlet",newPayServlet());}}基于xml方式啟Maven依賴信publicclassMyMvcConfig}配置文件內publicpublicclassWebInitializerimplementsWebApplicationInitializerpublicvoidonStartup(javax.servlet.ServletContextservletContext)ServletException 創(chuàng)建SpringMVC容AnnotationConfigWebApplicationContextapp=//2.我們的配置文 我們DispatcherServletdispatcherServlet=newDispatcherServlet(app);ServletRegistration.Dynamicdynamic=servletContext.addServlet("dispatcherServlet",dispatcherServlet);dynamic.setLoadOnStartup(1);//最優(yōu)先啟}}}Jsp視圖publicpublicViewResolverviewResolver()InternalResourceViewResolverinternalResourceViewResolver=new前internalResourceViewResolver.setPrefix("/WEB-//后綴returninternalResourceViewResolver;}<%@pagelanguage="java"contentType="text/html;charset=UTF-我是完全注解方式整合SpringMVC器使用器和過濾器都是基于Aop實現,能夠對請求執(zhí)行之前和之后實現。ServletWeb器不需要依賴于Servlet、不僅可以實現Web請求還有其他方法等SpringMVC器的使1.自定義請求pletion在DispatcherServletpublicpublicclassTokenInterceptorimplementsHandlerInterceptorpublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponsere

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論