杭州电子科技大学

依赖注入  时间:2021-02-19  阅读:()
Spring,2012软件系统设计与体系架构(J2EE)第5章:Spring之旅Spring之旅Spring概述SpringIoCSpringMVCSpring概述Spring概述什么是Spring框架(SpringFramework)Java平台上的一个开源应用框架实现了IoC(InversionofControl)模式采用分层架构,允许选择使用哪一个组件为J2EE应用程序开发提供集成的框架http://www.
springsource.
org/Spring概述为什么采用Spring框架(SpringFramework)解决企业应用程序开发复杂性通过程序对象的松散耦合(Loosecoupling),使得整个应用程序可以在架构与维护上得到相当程度的简化Don'tReinventtheWheelSpring概述Spring框架的历史来源RodJohnson:《ExpertOne-On-OneJavaEEDesignandDevelopment》Spring概述Spring框架的历史2003年2月在著名的开源社区"Sourceforge"上,一批自愿拓展Spring框架的程序开发员组成了团队,构建了一个项目2004年3月发布了第一个版本(1.
0)2007年底发布:Spring2.
52009年底发布:Spring3.
0当前版本:Spring3.
1.
1Spring概述ThemissionofSpringJ2EEshouldbeeasiertouseItisbesttoprogramtointerfaces,ratherthanclasses.
JavaBeansofferagreatwayofconfiguringapplications.
OOdesignismoreimportantthananyimplementationtechnology,suchasJ2EE.
CheckedexceptionsareoverusedinJava.
Aplatformshouldn'tforceyoutocatchexceptionsyou'reunlikelytobeabletorecoverfrom.
Testabilityisessential,andaplatformsuchasSpringshouldhelpmakeyourcodeeasiertotest.
Spring概述http://www.
springsource.
org/Spring概述Spring框架的七个模块核心容器Spring上下文SpringAOPSpringDAOSpringORMSpringWeb模块SpringMVC框架Spring概述IoC(InversionofControl):控制反转也可叫做DI(DependencyInjection):依赖注入不直接创建对象,但是描述创建它们的方式在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务容器(在Spring框架中是IoC容器)负责将这些联系在一起HollywoodPrinciple:Don'tcallus,We'llcallyou!
Spring概述AOP:面向方面编程1990年开始,来自XeroxPaloAltoResearchLab的研究人员对面向对象思想的局限性进行了分析,研究出了一种新的编程思想通过减少代码重复模块帮助开发人员提高工作效率Spring概述轻量级(Lightweight)相对于"重量级"而言在Spring出现之前,企业级开发一般都采用EJB,因为它提供的事务管理,声明式事务支持,持久化,分布计算等等都"简化"了企业级应用的开发重量级容器是一种入侵式的要用EJB提供的功能就必须在代码中体现出来使用的是EJB,比如继承一个接口,声明一个成员变量.
这样就把代码绑定在EJB技术上了Spring概述轻量级(Lightweight)Spring提供了一种轻量级的解决方案,用于建立快速企业应用Spring核心只有不到1MB的大小Spring是个非侵入性(Nonintrusive)框架让应用程序不感受到框架的存在,减低应用程序从框架移植时的负担Spring概述其他轻量级容器PicoContainerhttp://www.
picocontainer.
orgAvalonApacheSoftwareLicensehttp://avalon.
apache.
orgNanoContainerhttp://www.
nanocontainer.
orgPeapodhttp://www.
peapod.
org/JFoxhttp://www.
huihoo.
org/Jdonhttp://www.
jdon.
com/Spring之旅Spring概述SpringIoCSpringMVCSpring的IoCIOC(控制反转)/DI(依赖注入)在Spring中,组件无需自己负责与其他组件的关联InSpring,objectsarenotresponsibleforfindingorcreatingtheotherobjectsthattheyneedtodotheirjob.
容器负责把关联组件的引用给予各个组件Instead,theyaregivenreferencestotheobjectsthattheycollaboratewithbythecontainer.
Spring的IoCSpring的IoC依赖注入(DependencyInjection)对象之间的依赖关系(即一起工作的其它对象)构造函数的参数、工厂方法的参数,或给由构造函数或者工厂方法创建的对象设置属性容器的工作就是创建bean时注入那些依赖关系相对于由bean自己来控制其实例化、直接在构造函数中指定依赖关系或类似服务定位器(ServiceLocator)模式这3种自主控制依赖关系注入的方法来说,控制从根本上发生了倒转控制反转(InversionofControl,IoC)名字的由来Spring的IoC如何配置BeanBean工厂、ApplicationContext创建Bean、注入Bean属性、自动装配Bean生命周期和控制BeanSpring的IoC配置Bean什么是BeanBean是由Spring容器初始化、装配及被管理的对象Bean定义以及Bean相互间的依赖关系将通过配置元数据来描述Spring的IoC配置Bean:Bean的命名约定采用标准的Java命名约定小写字母开头,首字母大写间隔如accountManager、accountService、userDao及loginController每个bean都有一个或多个id(或称之为标识符或名称)这些id在当前IoC容器中必须唯一如果一个bean有多个id,那么其他的id在本质上将被认为是别名Spring的IoCBean工厂BeanFactory是SpringIoC容器的实际代表者org.
springframework.
beans.
factory.
BeanFactorySpring中IoC容器是对象的加工厂,可以按照元数据填充和组装Java对象BeanFactory是IoC容器的核心接口,职责包括:实例化、定位、配置应用程序中的对象及创建这些对象间的依赖Spring的IoCBean工厂:创建Bean工厂Spring提供了许多易用的BeanFactory实现XmlBeanFactory类是最常用的一个以XML方式描述组成应用的对象以及对象间的依赖关系XmlBeanFactory类将持有此XML配置元数据,并用它来构建一个完全可配置的系统或应用示例BeanFactoryfactory=newXmlBeanFactory(newFileSystemResource("c:/beans.
xml"));Spring的IoCBean工厂:获取Beanbean定义描述了创建一个或多个实际bean对象的内容在需要的时候,容器会从bean定义列表中取得一个指定的bean定义,并根据bean定义里面的配置元数据使用反射机制来创建一个实际的对象示例MyBeanmyBean=(MyBean)factory.
getBean("myBean");Spring的IoCBean工厂:BeanFactory的方法booleancontainsBean(String)如果BeanFactory包含给定名称的bean定义(或bean实例),则返回trueObjectgetBean(String)返回以给定名字注册的bean实例如果为singleton模式将返回一个共享的实例,否则将返回一个新建的实例如果没有找到指定的bean,该方法可能会抛出BeansException异常Spring的IoC利用ApplicationContextApplicationContext与BeanFactory类似ApplicationContext扩展BeanFactory接口主要功能:装入Bean定义信息,装配Bean,根据需要分发BeanApplicationContext提供更多功能提供消息解析方法,包括国际化支持消息提供装载文件资源(如图片)方法可以向注册为监听器的Bean发送事件Applicationcontextscanpublisheventstobeansthatareregisteredaslisteners.
Spring的IoC利用ApplicationContextApplicationContext的常用实现ClassPathXmlApplicationContext从类路径中的XML文件中装入上下文定义ApplicationContextcontext=newClassPathXmlApplicationContext("foo.
xml");FileSystemXmlApplicationContext从文件系统中的XML文件中装入上下文定义ApplicationContextcontext=newFileSystemXmlApplicationContext("c:/foo.
xml");XmlWebApplicationContext从Web应用中的XML文件中装入上下文定义Spring的IoC利用ApplicationContext从ApplicationContext中获取Bean使用getBean()方法对于单实例Bean,ApplicationContext将在上下文启动之后一次性装载Abeanfactorylazilyloadsallbeans,deferringbeancreationuntilthegetBean()methodiscalled.
Spring的IoCSpringIOC之旅:SpringIdolCompetition预备:所有选手必须实现Perform()接口publicinterfacePerformer{voidperform()throwsPerformanceException;}Spring的IoCSpringIOC之旅:SpringIdolCompetition第一个选手:Duke:Jugglerpackageedu.
hdu.
springidol;publicclassJugglerimplementsPerformer{privateintbeanBags=3;publicJuggler(){}publicJuggler(intbeanBags){this.
beanBags=beanBags;}publicvoidperform()throwsPerformanceException{System.
out.
println("JUGGLING"+beanBags+"BEANBAGS");}}Spring的IoCSpringIOC之旅:SpringIdolCompetition第一个选手:Duke:Jugglerspring_idol1.
xml应用程序代码(SpringIdolMain1.
java)ApplicationContextctx=newClassPathXmlApplicationContext("com/springinaction/springidol/spring-juggle-noconstructor.
xml");Performerperformer=(Performer)ctx.
getBean("duke");performer.
perform();运行结果JUGGLING3BEANBAGS注意:需要引入包:spring.
jar,commons-logging.
jar,log4j-1.
2.
15.
jarSpring的IoCSpringIOC之旅:SpringIdolCompetition第一个选手:Duke:JugglerButjugglingthreebeanbagsisn'tallthatimpressive—anybodycandothat.
通过构造函数注入(spring_idol2.
xml)元素用来告诉Spring如何创建一个Bean如果没有,将调用缺省构造器应用程序SpringIdolMain2.
javaspring_idol2.
xmlSpring的IoCSpringIOC之旅:SpringIdolCompetition第一个选手:Duke:poeticjugglerpackageedu.
hdu.
springidoll;publicclassPoeticJugglerextendsJuggler{privatePoempoem;publicPoeticJuggler(Poempoem){super();this.
poem=poem;}publicPoeticJuggler(intbeanBags,Poempoem){super(beanBags);this.
poem=poem;}publicvoidperform()throwsPerformanceException{super.
perform();System.
out.
println("WHILERECITING.
.
.
");poem.
recite();}}Spring的IoCSpringIOC之旅:SpringIdolCompetition第一个选手:Duke:poeticjugglerpublicinterfacePoem{voidrecite();}packageedu.
hdu.
springidol;publicclassSonnet29implementsPoem{privatestaticString[]LINES={"When,indisgracewithfortuneandmen'seyes,","Iallalonebeweepmyoutcaststate","Andtroubledeafheavenwithmybootlesscries","Andlookuponmyselfandcursemyfate,","Wishingmeliketoonemorerichinhope,","Featuredlikehim,likehimwithfriendspossess'd,","Desiringthisman'sartandthatman'sscope,",当我受尽命运和人们的白眼,暗暗地哀悼自己的身世飘零,徒用呼吁去干扰聋瞆的昊天,顾盼着身影,诅咒自己的生辰,愿我和另一个一样富于希望,面貌相似,又和他一样广交游,希求这人的渊博,那人的内行,Spring的IoCSpringIOC之旅:SpringIdolCompetition第一个选手:Duke:poeticjuggler"WithwhatImostenjoycontentedleast;","Yetinthesethoughtsmyselfalmostdespising,","HaplyIthinkonthee,andthenmystate,","Liketothelarkatbreakofdayarising","Fromsullenearth,singshymnsatheaven'sgate;","Forthysweetloveremember'dsuchwealthbrings","ThatthenIscorntochangemystatewithkings.
"};publicSonnet29(){}publicvoidrecite(){for(inti=0;i应用程序SpringIdolMain3.
javaSpring的IoCSpringIOC之旅:SpringIdolCompetition第二个选手:Kenny:instrumentalistpackageedu.
hdu.
springidol;publicclassInstrumentalistimplementsPerformer{publicInstrumentalist(){}publicvoidperform()throwsPerformanceException{System.
out.
print("Playing"+songinstrument.
play();}privateStringsong;publicvoidsetSong(Stringsong){this.
song=song;}privateInstrumentinstrument;publicvoidsetInstrument(Instrumentinstrument){this.
instrument=instrument;}}Spring的IoCSpringIOC之旅:SpringIdolCompetition第二个选手:Kenny:instrumentalistpublicinterfaceInstrument{voidplay();}springidol.
xmlProblemKenny没有歌曲和乐器,如何演奏Spring的IoCSpringIOC之旅:SpringIdolCompetition第二个选手:Kenny:instrumentalist(注入简单属性)spring_idol4.
xml元素告诉Spring调用setSong()方法设置song属性为"JingleBells",类似于:InstrumentalistKenny=newInstrumentalist();Kenny.
setSong("JingleBells");演奏者与演奏曲子之间并不是硬编码的(hard-coded):松耦合Spring的IoCSpringIOC之旅:SpringIdolCompetition第二个选手:Kenny:instrumentalist(注入其他Bean)publicclassSaxophoneimplementsInstrument{publicSaxophone(){}publicvoidplay(){System.
out.
println("TOOTTOOTTOOT");}}spring-instrumentalist.
xmlSpring的IoCSpringIOC之旅:SpringIdolCompetition第二个选手:Kenny:instrumentalist应用程序(SpringIdolMain4.
java)ApplicationContextctx=newClassPathXmlApplicationContext("edu/hdu/springidol/spring_idol4.
xml");Performerperformer=(Performer)ctx.
getBean("kenny");performer.
perform();执行结果PlayingJingleBells:TOOTTOOTTOOTSpring的IoCSpringIOC之旅:SpringIdolCompetition第二个选手:Kenny:instrumentalist增加另外一种乐器(Piano)packagecom.
springinaction.
springidol;publicclassPianoimplementsInstrument{publicPiano(){}publicvoidplay(){System.
out.
println("PLINKPLINKPLINK");}}Spring的IoCSpringIOC之旅:SpringIdolCompetition第二个选手:Kenny:instrumentalist增加另外一种乐器(Piano)spring_idol5.
xml执行结果(SpringIdolMain5.
java)PlayingJingleBells:PLINKPLINKPLINKKennywillplayapianoinsteadofasaxophone!
Spring的IoCSpringIOC之旅:SpringIdolCompetition第二个选手:Kenny:instrumentalist内部Bean:定义在某个Bean的内部instruments;publicvoidsetInstruments(Collectioninstruments){this.
instruments=instruments;}}Spring的IoCSpringIOC之旅:SpringIdolCompetition第三个选手:Hank:one-man-band(使用list)spring_idol6.
xmlSpring的IoCSpringIOC之旅:SpringIdolCompetition第三个选手:Hank:one-man-band(使用list)程序SpringIdolMain6.
javaspring-idol6.
xml执行结果STRUMSTRUMSTRUMTOOTTOOTTOOTCRASHCRASHCRASHCRASHCRASHCRASHSpring的IoCSpringIOC之旅:SpringIdolCompetition第三个选手:Hank:one-man-band(使用Properties)应用程序(OneManBandProperties.
java)publicclassOneManBandPropertiesimplementsPerformer{publicOneManBandProperties(){}publicvoidperform()throwsPerformanceException{for(Iteratoriter=instruments.
keySet().
iterator();iter.
hasNext();){Stringkey=(String)iter.
next();System.
out.
println(keyinstruments.
getProperty(key));}}privatePropertiesinstruments;publicvoidsetInstruments(Propertiesinstruments){this.
instruments=instruments;}}Spring的IoCSpringIOC之旅:SpringIdolCompetition第三个选手:Hank:one-man-band(使用Properties)spring-idol7.
xmlSTRUMSTRUMSTRUMCRASHCRASHCRASHHUMHUMHUMSpring的IoCSpringIOC之旅:SpringIdolCompetition第三个选手:Hank:one-man-band(使用Properties)程序SpringIdolMain7.
javaspring-idol7.
xml执行结果HARMONICA:HUMHUMHUMCYMBAL:CRASHCRASHCRASHGUITAR:STRUMSTRUMSTRUMSpring的IoC自动装配(autodetect)首先使用构造器匹配,如果匹配不到再根据类型匹配示例Spring概述Spring概述SpringIoCSpringMVCSpring的MVC什么是MVCSpring的MVCDispatcherServletDispatcherServlet:前端控制器是一个servlet前端控制其把请求转给其他组件(控制器)转给哪个控制器Spring的MVCDispatcherServlet请求生命中的一天分配器(DispatchServlet)接收Servlet请求分配器通过处理器映射(HandlerMapping)选择合适的控制器给某个请求控制器是一个用来处理请求的Spring组件一个典型的Spring应用可包含多个控制器Spring的MVCDispatcherServlet请求生命中的一天(续)控制器执行业务逻辑,返回视图和模型给分配器DispatcherServlet把请求转发给所选择的控制器控制器根据用户提交的请求信息进行适当的处理控制器把模型数据和视图名称打包为一个ModelAndView对象分配器根据视图解析器,选择合适的视图DispatcherServlet通过视图解析器(viewresolver)找到需要的视图(一般为某个JSP页面)视图利用模型数据(modeldata)渲染页面页面通过响应对象被发送回浏览器Spring的MVCDispatcherServlet配置DispatcherServlet和其它Servlet一样,DispatcherServlet定义在web应用的web.
xml文件里roadrantzorg.
springframework.
web.
servlet.
DispatcherServlet1roadrantz*.
htmSpring的MVCDispatcherServlet配置DispatcherServlet缺省的应用程序上下文配置文件:如何确定配置文件名Spring的应用上下文配置文件的名称与servlet名称有关缺省:[servlet名称]-servlet.
xml建议使用多个配置文件Spring的MVCDispatcherServlet配置DispatcherServlet配置上下文载入器(为了载入更多的配置文件)AcontextloaderloadscontextconfigurationfilesinadditiontotheonethatDispatcherServletloads.
(web.
xml)org.
springframework.
web.
context.
ContextLoaderListener定义配置文件(web.
xml)contextConfigLocation/WEB-INF/roadrantz-service.
xml/WEB-INF/roadrantz-data.
xml/WEB-INF/roadrantz-security.
xmlSpring的MVCSpringMVC小例子主要任务第1步:编写控制器类,用以执行隐藏在页面后的逻辑例如:调用RantService获得最近的抱怨列表第2步:在分配器的上下文配置文件中配置控制器类例如:在roadrantz-servlet.
xml中配置第3步:配置一个视图解析器,以绑定该控制器至某个JSP页面第4步:编写该JSP页面Spring的MVCSpringMVC小例子第一步:创建控制器publicclassHomePageControllerextendsAbstractController{.
.
.
}Spring的MVCSpringMVC小例子第一步:创建控制器publicclassHomePageControllerextendsAbstractController{publicHomePageController(){}protectedModelAndViewhandleRequestInternal(HttpServletRequestrequest,HttpServletResponseresponse)throwsException{ListrecentRants=rantService.
getRecentRants();returnnewModelAndView("home","rants",recentRants);}privateRantServicerantService;publicvoidsetRantService(RantServicerantService){this.
rantService=rantService;}}Spring的MVCSpringMVC小例子第一步:创建控制器(引入ModelAndView)一个ModelAndView对象封装了视图和模型数据newModelAndView("home","rants",recentRants);构造器的第一个参数是下一步将要使用的视图的逻辑名(视图解析器将使用该逻辑名寻访实际的视图对象)构造器的第二/三个参数代表了将被传递给视图的模型数据第二/三个参数是一个"名称-值"对第二个参数是是模型对象(由第三个参数给出)的名称Spring的MVCSpringMVC小例子第二步:配置控制器Bean配置示例当一个以/home.
htm为结尾的请求达到DispatcherServlet时,DispatcherServlet将分配该请求至HomePageController以继续处理Spring的MVCSpringMVC小例子第三步:申明一个视图解析器/WEB-INF/jsp/.
jspInternalResourceViewResolver将寻找名为home的视图为:/WEB-INF/jsp/home.
jsp.
Spring的MVCSpringMVC小例子第四步:创建JSP(/WEB-INF/jsp/home.
jsp)RantzWelcometoRoadRantz!
Recentrantz:/--Spring的MVCSpringMVC小例子合并起来1)DispatcherServlet收到URL形式为/home.
htm的请求2)DispatcherServlet通过调用BeanNameUrlHandlerMapping方法找到某个控制器,它的bean名称为/home.
htm例子中找到的是HomePageController控制器分配器处理器控制器Spring的MVCSpringMVC小例子合并起来(续)3)DispatcherServlet把请求转发给HomePageController处理4)HomePageController返回一个ModelAndView对象,其中包括名为home的逻辑视图,和存放在rants中的抱怨列表Spring的MVCSpringMVC小例子合并起来(续)5)DispatcherServlet通过视图解析器(这里配置为InternalResourceViewResolver)找到逻辑名称为home的视图.
InternalResourceViewResolver返回/WEB-INF/jsp/home.
jsp6)DispatcherServlet把请求转发给/WEB-INF/jsp/home.
jsp,后者渲染页面并回传给用户Spring的MVC深入一:如何将请求映射到控制器Spring提供了4个处理器实现实现接口:org.
springframework.
web.
servlet.
HandlerMapping1)BeanNameUrlHandlerMapping(缺省)将控制器映射到根据控制器名字确定的URL2)SimpleUrlHandlerMapping根据上下文配置文件中的属性集合将控制器映射到URL3)ControllerClassNameHandlerMapping通过将控制器的类名作为URL的基础将控制器映射到URL4)CommonsPathMapHandlerMapping根据控制器代码中的元数据将控制器映射到URL元数据使用JakartaCommonsAttributes(http://jakarta.
apache.
org/commons/attributes)定义Spring的MVC深入一:如何将请求映射到控制器2)使用SimpleUrlHandlerMappinghomePageControllerrantsForVehicleControllerrantsForVehicleControllerRssrantsForDayControllerloginControllerregisterMotoristControlleraddRantControllerSpring的MVC深入一:如何将请求映射到控制器3)使用ControllerClassNameHandlerMapping一个控制器按照以下规则映射到某个请求去除控制器类名称的Controller部分(如存在)全部小写开头增加:/结尾增加:.
htmSpring的MVC深入一:如何将请求映射到控制器使用多映射处理器Order属性值越小,优先级越高10…Spring的MVC深入二:用控制器处理请求SpringMVC的控制器层次Spring的MVC深入二:用控制器处理请求SpringMVC可选控制器视图控制器(ParameterizableViewController,UrlFilenameViewController)仅仅显示静态视图,没有处理,无须获取数据简单控制器(Controller,AbstractController)非常简单,类似于一般的servlet一次性控制器(ThrowawayController)类似于命令方式处理请求多动作控制器(MultiActionController)可执行多个关联动作Spring的MVC深入二:用控制器处理请求SpringMVC可选控制器(续)命令控制器(BaseCommandController,AbstractCommandController)控制器会从请求接受一个或多个参数,然后将它们绑定到一个对象中,可提供参数验证的功能表单控制器(AbstractFormController,SimpleFormController)需要给用户显示一个输入表单,并且处理输入表单的数据向导控制器(AbstractWizardFormController)带领用户通过一个复杂的、多页面的输入表单,最后按一个表单处理Spring的MVC深入二:用控制器处理请求1)使用命令控制器AbstractCommandController会自动把HTTP请求参数绑定到命令对象中,并且提供了插入验证器的钩子,以确保参数的合法性publicclassRantsForVehicleControllerextendsAbstractCommandController{publicRantsForVehicleController(){setCommandClass(Vehicle.
class);setCommandName("vehicle");}Spring的MVC深入二:用控制器处理请求1)使用命令控制器在handler方法调用之前,Spring将试图把请求中的任务参数匹配到命令对象的属性中protectedModelAndViewhandle(HttpServletRequestrequest,HttpServletResponseresponse,Objectcommand,BindExceptionerrors)throwsException{Vehiclevehicle=(Vehicle)command;ListvehicleRants=rantService.
getRantsForVehicle(vehicle));Mapmodel=errors.
getModel();model.
put("rants",rantService.
getRantsForVehicle(vehicle));model.
put("vehicle",vehicle);returnnewModelAndView("vehicleRants",model);}Spring的MVC深入二:用控制器处理请求1)使用命令控制器(续)privateRantServicerantService;publicvoidsetRantService(RantServicerantService){this.
rantService=rantService;}}配置控制器Spring的MVC深入三:视图解析一个视图就是一个将结果渲染给用户的Bean如何完成渲染取决于使用的视图类型JSP,Velocity,FreeMarker,PDF,Excel视图解析器把赋给ModelAndView对象的逻辑视图名解析成一个用于将结果渲染给用户的视图Bean实现了org.
springframework.
web.
servlet.
ViewResolver接口Spring的MVC深入三:视图解析常用视图解析器InternalResourceViewResolver将逻辑视图名解析为一个用模板文件(如JSP和Velocity模板)渲染的视图对象BeanNameViewResolver在Spring上下文环境中查找实现了View接口的Bean,假设Bean的名称就是逻辑视图的名称Spring的MVC深入三:视图解析常用视图解析器(续)ResourceBundleViewResolver使用资源捆绑(即利用属性文件)将逻辑视图名称映射为View接口的实现XmlViewResolver从一个XML文件中解析视图Bean,这个文件是从应用上下文中分离出来的Spring的MVC深入三:视图解析使用视图解析器:InternalResourceViewResolver在控制器中returnnewModelAndView("vehicleRants","rants",vehicleRants);在上下文配置文件中Spring概述SpringIoCSpringMVCSpring之旅

湖北22元/月(昔日数据)云服务器,国内湖北十堰云服务器,首月6折

昔日数据怎么样?昔日数据新上了湖北十堰云服务器,湖北十堰市IDC数据中心 母鸡采用e5 2651v2 SSD MLC企业硬盘 rdid5阵列为数据护航 100G高防 超出防御峰值空路由2小时 不限制流量。目前,国内湖北十堰云服务器,首月6折火热销售限量30台价格低至22元/月。(注意:之前有个xrhost.cn也叫昔日数据,已经打不开了,一看网站LOGO和名称为同一家,有一定风险,所以尽量不要选择...

Asiayun:枣庄电信Asiayun美国Cera葵湾VPSvps月付,美国CERA VPS月付26元/年

亚洲云Asiayun怎么样?亚洲云成立于2021年,隶属于上海玥悠悠云计算有限公司(Yyyisp),是一家新国人IDC商家,且正规持证IDC/ISP/CDN,商家主要提供数据中心基础服务、互联网业务解决方案,及专属服务器租用、云服务器、云虚拟主机、专属服务器托管、带宽租用等产品和服务。Asiayun提供源自大陆、香港、韩国和美国等地骨干级机房优质资源,包括BGP国际多线网络,CN2点对点直连带宽以...

AlphaVPS(€3.99/月)VPS年付15欧,AMD EYPC+NVMe系列起

AlphaVPS是一家保加利亚本土主机商(DA International Group Ltd),提供VPS主机及独立服务器租用等,数据中心包括美国(洛杉矶/纽约)、德国、英国和保加利亚等,公司办公地点跟他们提供的保加利亚数据中心在一栋楼内,自有硬件,提供IPv4+IPv6,支持PayPal或者信用卡等方式付款。商家提供的大硬盘VPS主机,提供128GB-2TB磁盘,最低年付15欧元起,也可以选择...

依赖注入为你推荐
popmundofuck是什么意思视频截图软件怎么在视频中剪切一张图片?用什么软件郭彩妮介紹點好聽的音樂給我、大家博客外链博客外链怎么做好万网核心代理我想买个域名和空间,我一朋友给我介绍万网代理环宇网络空间商,他们的空间稳定吗,价格怎么样,咨询师的服flash导航条FLASH导航条 怎么加入链接?依赖注入依赖注入是什么意思?今日热点怎么删除今日热点自动弹出怎么卸载或屏蔽硬盘人上海人说“硬盘”是什么梗宕机宕机是什么意思?
西部数码vps net主机 精品网 59.99美元 20g硬盘 网站保姆 panel1 东莞服务器 shopex主机 web服务器搭建 国外在线代理服务器 1美元 tracker服务器 碳云 塔式服务器 server2008 低价 vpsaa 中国最年轻博士 免费邮件服务器软件 更多