热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SpringFramework核心技术一(IOC:Bean的范围)

Bean的范围当你创建一个bean定义时,你创建一个配方来创建由该bean定义定义的类的实际实例。bean定义是一个配方的想法很重要,因为它意味着&#x

Bean的范围

当你创建一个bean定义时,你创建一个配方来创建由该bean定义定义的类的实际实例。bean定义是一个配方的想法很重要,因为它意味着,就像一个类一样,您可以从一个配方创建许多对象实例。
您不仅可以控制要插入到从特定的bean定义创建的对象中的各种依赖项和配置值,还可以控制从特定的bean定义创建的对象的范围。这种方法功能强大且灵活,因为您可以选择通过配置创建的对象的范围,而不必在Java类级别上烘焙对象的范围。Bean可以被定义为部署在多个作用域中的一个:

Spring框架支持六个作用域,其中四个作用域仅在使用Web感知时才可用ApplicationContext。

一、Bean的范围域

Scope(作用域)Description(描述)
singleton(单例)(默认)每个Spring IoC容器将单个bean定义作用于单个对象实例。
prototype(原型)Scopes a single bean definition to any number of object instances.将任何数量的对象实例的单个bean定义作用域。
request(请求)将单个bean定义作用于单个HTTP请求的生命周期; 也就是说,每个HTTP请求都有自己的实例,这个实例是在单个bean定义的背后创建的。只有在Web认知的Spring环境中才有效ApplicationContext。
session(会话作用域)将一个单一的bean定义作用于HTTP的生命周期Session。只有在Web认知的Spring环境中才有效ApplicationContext。
application(应用作用域)将范围定义为a的生命周期的单个bean定义ServletContext。只有在Web认知的Spring环境中才有效ApplicationContext。
websocket(websocket作用域)将范围定义为a的生命周期的单个bean定义WebSocket。只有在Web认知的Spring环境中才有效ApplicationContext。

二、singleton单例作用域

  • 只管理单个bean的一个共享实例,并且具有与该bean定义匹配的id或id的bean的所有请求都会导致Spring容器返回一个特定的bean实例。
    换句话说,当你定义一个bean定义并将其作为一个singleton作用域时,Spring IoC容器恰好创建了该bean定义的对象的一个实例。这个单实例存储在这些单例bean的缓存中,并且该命名bean的所有后续请求和引用都会返回缓存的对象。
    这里写图片描述
  • Spring的单例bean概念与四人帮(GoF)模式书中定义的Singleton模式不同。GoF Singleton对对象的范围进行硬编码,以便每个ClassLoader创建一个特定类的唯一实例。Spring单例的范围最好按容器和每个bean来描述。这意味着如果您为单个Spring容器中的特定类定义一个bean,那么Spring容器将创建该bean定义所定义的类的一个且仅有的一个实例。单例作用域是Spring中的默认作用域。要将一个bean定义为XML中的单例,您可以编写,例如:


<bean id&#61;"accountService" class&#61;"com.foo.DefaultAccountService"/>
<bean id&#61;"accountService" class&#61;"com.foo.DefaultAccountService" scope&#61;"singleton"/>

三、The prototype scope&#xff08;原型作用域&#xff09;

  • 生命周期不由Spring容器来管理
  • bean的部署的非单实例原型范围导致每次创建一个新的bean实例时&#xff0c;都会创建一个对该特定bean的请求。也就是说&#xff0c;该bean被注入到另一个bean中&#xff0c;或者通过getBean()容器上的方法调用来请求它。通常&#xff0c;为所有有状态bean和无状态bean的单例作用域使用原型作用域。
  • 下图说明了Spring原型范围。数据访问对象&#xff08;DAO&#xff09;通常不配置为原型&#xff0c;因为典型的DAO不具有任何对话状态; 这位作者更容易重用单体图的核心。
    这里写图片描述
  • 以下示例在XML中将bean定义中的原型作用域&#xff1a;

"accountService" class&#61;"com.foo.DefaultAccountService" scope&#61;"prototype"/>

  • 与其他范围相比&#xff0c;Spring不管理原型bean的完整生命周期&#xff1a;容器实例化&#xff0c;配置和以其他方式组装原型对象&#xff0c;并将其交给客户端&#xff0c;而不再记录该原型实例。因此&#xff0c;尽管在所有对象上调用初始化生命周期回调方法而不管范围&#xff0c;但在原型的情况下&#xff0c;不调用配置的销毁 生命周期回调。客户端代码必须清理原型范围的对象并释放原型bean持有的昂贵资源。为了让Spring容器释放原型范围bean所拥有的资源&#xff0c;请尝试使用自定义bean后期处理器&#xff0c;它拥有对需要清理的bean的引用。
    在某些方面&#xff0c;Spring容器在原型范围bean方面的作用是Java new操作符的替代。所有生命周期管理过去都必须由客户来处理。&#xff08;有关Spring容器中bean的生命周期的详细信息&#xff0c;请参阅生命周期回调。&#xff09;

四、Singleton beans with prototype-bean dependencies&#xff08;具有原型bean依赖关系的单例bean&#xff09;

  • 当您使用具有原型bean依赖关系的单一范围bean时&#xff0c;请注意&#xff0c; 在实例化时会解析依赖关系。因此&#xff0c;如果您将原型范围的bean依赖注入到单例范围的bean中&#xff0c;则将实例化新的原型bean&#xff0c;然后将依赖注入到单例bean中。原型实例是唯一提供给单例范围bean的唯一实例。
  • 但是&#xff0c;假设您希望单例范围的bean在运行时重复获取原型范围的bean的新实例。你不能依赖注入一个原型范围的bean到你的单例bean中&#xff0c;因为这个注入只发生 一次&#xff0c;当Spring容器实例化单例bean并解析和注入它的依赖关系时。如果您不止一次在运行时需要一个原型bean的新实例&#xff0c;请参阅方法注入。

五、 Request, session, application, and WebSocket scopes&#xff08;请求、会话、应用程序和WebSocket范围&#xff09;

  • request&#xff0c;session&#xff0c;application&#xff0c;和websocket范围域仅在你如果使用**基于web的Spring容器**ApplicationContext实现&#xff08;如 XmlWebApplicationContext&#xff09;。
  • 如果你将这些范围用于常规的Spring IoC容器&#xff08;非基于web的容器&#xff09;&#xff08;比如ClassPathXmlApplicationContext&#xff09;&#xff0c;那么IllegalStateException会抛出一个抱怨未知bean范围的问题。
    具体表现在以下五个方面&#xff1a;

1.初始网页配置

为了支持Bean的范围界定在request&#xff0c;session&#xff0c;application&#xff0c;和 websocket&#xff08;即具有web作用域bean&#xff09;&#xff0c;在你定义你的Bean之前需要做少量的初始配置。&#xff08;这些初始设置对于标准的范围域是不需要的例如&#xff1a;singleton和prototype&#xff09;。
您如何完成此初始设置取决于您特定的Servlet环境。
如果你在Spring Web MVC中访问范围化的bean&#xff0c;实际上&#xff0c;在由Spring处理的请求中DispatcherServlet&#xff0c;不需要特别的设置&#xff1a; DispatcherServlet已经公开了所有相关的状态。
如果您使用Servlet 2.5 Web容器&#xff0c;并且在Spring之外处理请求 DispatcherServlet&#xff08;例如&#xff0c;使用JSF或Struts时&#xff09;&#xff0c;则需要注册 org.springframework.web.context.request.RequestContextListener ServletRequestListener。对于Servlet 3.0&#43;&#xff0c;这可以通过WebApplicationInitializer 接口以编程方式完成。或者&#xff0c;对于较旧的容器&#xff0c;将以下声明添加到Web应用程序的web.xml文件中&#xff1a;

...org.springframework.web.context.request.RequestContextListener...

或者&#xff0c;如果您的监听器设置存在问题&#xff0c;请考虑使用Spring’s RequestContextFilter&#xff08;过滤器&#xff09;。过滤器映射取决于周围的Web应用程序配置&#xff0c;因此您必须根据需要进行更改。

...requestContextFilterorg.springframework.web.filter.RequestContextFilterrequestContextFilter/*...

DispatcherServlet&#xff0c;RequestContextListener并且RequestContextFilter都做完全相同的事情&#xff0c;即将HTTP请求对象绑定到Thread服务该请求的对象。这使得请求和会话范围的bean可以在调用链的更下方进行访问。

2. Request scope&#xff08;请求范围&#xff09;

考虑以下用于bean定义的XML配置&#xff1a;

"loginAction" class&#61;"com.foo.LoginAction" scope&#61;"request"/>

Spring容器LoginAction通过loginAction为每个HTTP请求使用bean定义来创建一个新的bean 实例。也就是说&#xff0c;这个 loginAction bean的作用域是HTTP请求级别。您可以根据需要更改创建的实例的内部状态&#xff0c;因为从同一个loginActionbean定义创建的其他实例将不会看到这些状态变化; 他们对个人的要求很特别。当请求完成处理时&#xff0c;作用于该请求的bean将被丢弃。

使用注释驱动组件或Java Config时&#xff0c;&#64;RequestScope可以使用注释将组件分配给request作用域。

&#64;RequestScope
&#64;Component
public class LoginAction {// ...
}

3.Session scope&#xff08;会话范围&#xff09;

考虑用以下的XML配置来定义一个会话范围&#xff1a;

"userPreferences" class&#61;"com.foo.UserPreferences" scope&#61;"session"/>

Spring容器UserPreferences通过在userPreferences单个HTTP的生命周期中使用bean定义来创建bean 的新实例Session。换句话说&#xff0c;这个userPreferencesbean的有效范围在HTTP Session级别。和request-scopedbean一样&#xff0c;您可以根据需要更改创建的实例的内部状态&#xff0c;因为知道其他Session使用同一个userPreferencesbean定义创建的实例的HTTP 实例也不会看到这些状态变化&#xff0c;因为它们是特定的到一个单独的HTTP Session。当HTTP Session最终被丢弃时&#xff0c;作用于该特定HTTP的bean Session也被丢弃。

使用注释驱动组件或Java Config时&#xff0c;&#64;SessionScope可以使用注释将组件分配给session作用域。

&#64;SessionScope
&#64;Component
public class UserPreferences {// ...
}

4.Application scope&#xff08;应用范围&#xff09;

考虑以下用以下的XML文件去给Bean定义一个应用程序的范围。

"appPreferences" class&#61;"com.foo.AppPreferences" scope&#61;"application"/>

Spring容器使用在整个Web应用程序只定义一次的appPreferences bean&#xff0c;创建一个新的appPreferences实例。
也就是说&#xff0c;这个 appPreferencesbean的作用域是ServletContext作为一个常规ServletContext属性存储的 。这有点类似于Spring单例bean&#xff0c;但在两个重要方面有所不同&#xff1a;它是单例ServletContext&#xff0c;而不是每个Spring’ApplicationContext’&#xff08;在任何给定的Web应用程序中可能有几个&#xff09;&#xff0c;它实际上是公开的&#xff0c;因此是可见的作为ServletContext属性

使用注释驱动组件或Java Config时&#xff0c;&#64;ApplicationScope 可以使用注释将组件分配给application作用域。

&#64;ApplicationScope
&#64;Component
public class AppPreferences {// ...
}

5. 作为依赖关系的作用域bean

Spring IoC容器不仅管理对象&#xff08;bean&#xff09;的实例化&#xff0c;还管理协作者&#xff08;或依赖项&#xff09;的连接。如果您想要将HTTP请求范围的bean注入&#xff08;例如&#xff09;一个更长寿命范围的另一个bean中&#xff0c;您可以选择注入一个AOP代理来代替范围bean。也就是说&#xff0c;您需要注入一个代理对象&#xff0c;该对象公开与作用域对象相同的公共接口&#xff0c;但也可以从相关作用域&#xff08;例如HTTP请求&#xff09;中检索真实目标对象&#xff0c;并将方法调用委托给实际对象。

您也可以在作为范围的bean之间使用singleton&#xff0c;然后通过可序列化的中间代理&#xff0c;因此可以在反序列化中重新获得目标单身bean。
针对范围的bean进行声明prototype时&#xff0c;共享代理上的每个方法调用都将导致创建一个新的目标实例&#xff0c;然后将该呼叫转发给该实例。
此外&#xff0c;范围代理不是以生命周期安全的方式从较短范围访问Bean的唯一方法。您也可以简单地声明您的注入点&#xff08;即构造函数/设置器参数或自动装配的字段&#xff09;ObjectFactory&#xff0c;从而允许getObject()每次需要时根据需要调用一次调用来检索当前实例 - 而无需保留实例或单独存储实例。
作为一个扩展的变体&#xff0c;你可以声明ObjectProvider哪个提供了几个额外的访问变体&#xff0c;包括getIfAvailable和getIfUnique。
调用JSR-330变体Provider&#xff0c;与每次检索尝试的Provider 声明和相应get()调用一起使用。

以下示例中的配置只有一行&#xff0c;但了解“原因”以及它“如何”很重要。


<beans xmlns&#61;"http://www.springframework.org/schema/beans"xmlns:xsi&#61;"http://www.w3.org/2001/XMLSchema-instance"xmlns:aop&#61;"http://www.springframework.org/schema/aop"xsi:schemaLocation&#61;"http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><bean id&#61;"userPreferences" class&#61;"com.foo.UserPreferences" scope&#61;"session"><aop:scoped-proxy/>bean><bean id&#61;"userService" class&#61;"com.foo.SimpleUserService"><property name&#61;"userPreferences" ref&#61;"userPreferences"/>bean>
beans>

要创建这样一个代理&#xff0c;可以将一个子元素插入到一个有作用域的bean定义中&#xff08;请参阅选择要创建的代理类型和 基于XML模式的配置&#xff09;。豆类的定义为何作用域的request&#xff0c;session和自定义范围水平要求元素&#xff1f;让我们来看看下面的单例bean定义&#xff0c;并将其与您需要为上述范围定义的内容进行对比&#xff08;请注意&#xff0c;下面的 userPreferencesbean定义是不完整的&#xff09;。

id&#61;"userPreferences" class&#61;"com.foo.UserPreferences" scope&#61;"session"/>
id&#61;"userManager" class&#61;"com.foo.UserManager"><property name&#61;"userPreferences" ref&#61;"userPreferences"/>

在前面的例子中&#xff0c;singleton bean userManager注入了对HTTP- Sessionscoped bean 的引用userPreferences。这里的要点是 userManagerbean是一个单独的实例&#xff1a;每个容器只会实例化一次&#xff0c;并且它的依赖关系&#xff08;在本例中只有一个userPreferencesbean&#xff09;也只能被注入一次。这意味着这个userManagerbean只会在完全相同的userPreferences对象上运行&#xff0c;也就是它最初注入的那个对象。

这不是将寿命较短的作用域bean注入到寿命较长的作用域bean时所需的行为&#xff0c;例如将一个HTTP- Sessionscoped协作bean作为依赖注入到singleton bean中。相反&#xff0c;您需要一个userManager 对象&#xff0c;并且在HTTP的生命周期中Session&#xff0c;您需要一个userPreferences特定于所述HTTP 的对象Session。因此&#xff0c;容器创建一个对象&#xff0c;该对象公开与UserPreferences该类完全相同的公共接口&#xff08;理想情况下是一个 UserPreferences实例的对象&#xff09;&#xff0c;该UserPreferences对象可以从作用域机制&#xff08;HTTP请求Session等&#xff09;获取真实 对象。容器将这个代理对象注入到userManagerbean中&#xff0c;但不知道这一点UserPreferences参考是一个代理。在这个例子中&#xff0c;当一个UserManager 实例在依赖注入UserPreferences对象上调用一个方法时&#xff0c;它实际上是在代理上调用一个方法。代理然后 UserPreferences从HTTP&#xff08;在本例中&#xff09;Session获取真实UserPreferences对象&#xff0c;并将方法调用委托给检索到的真实对象。

因此&#xff0c;你注射时需要以下&#xff0c;准确&#xff0c;完整&#xff0c;配置 request-和session-scoped bean到协作对象&#xff1a;

id&#61;"userPreferences" class&#61;"com.foo.UserPreferences" scope&#61;"session">
id&#61;"userManager" class&#61;"com.foo.UserManager"><property name&#61;"userPreferences" ref&#61;"userPreferences"/>

选择要创建的代理类型
默认情况下&#xff0c;当Spring容器为使用元素标记的bean创建代理时&#xff0c;将创建一个基于CGLIB的类代理。

CGLIB代理只拦截公共方法调用&#xff01;不要在这样的代理上调用非公共方法; 它们不会被委派给实际的作用域目标对象。

或者&#xff0c;可以通过指定元素false的proxy-target-class属性值来配置Spring容器&#xff0c;以便为此类范围的bean创建标准的基于JDK接口的代理。使用基于JDK接口的代理意味着在应用程序类路径中不需要额外的库来实现这种代理。但是&#xff0c;这也意味着作用域bean的类必须至少实现一个接口&#xff0c;并且注入了作用域bean的所有协作者都必须通过它的一个接口引用bean。


<bean id&#61;"userPreferences" class&#61;"com.foo.DefaultUserPreferences" scope&#61;"session"><aop:scoped-proxy proxy-target-class&#61;"false"/>
bean><bean id&#61;"userManager" class&#61;"com.foo.UserManager"><property name&#61;"userPreferences" ref&#61;"userPreferences"/>
bean>

六、自定义范围

bean范围机制是可扩展的; 您可以定义自己的作用域&#xff0c;甚至可以重新定义现有的作用域&#xff0c;尽管后者被认为是不好的做法&#xff0c;并且不能覆盖内置singleton和prototype作用域。

1 创建一个自定义范围

要将自定义作用域集成到Spring容器中&#xff0c;需要实现org.springframework.beans.factory.config.Scope本节所述的 接口。有关如何实现自己的作用域的想法&#xff0c;请参阅Scope 随Spring Framework本身和Scopejavadoc提供的实现 &#xff0c;它解释了您需要更详细地实现的方法。
该Scope接口有四种方法来从作用域中获取对象&#xff0c;将它们从作用域中移除并允许它们被销毁。

以下方法从基础范围返回对象。例如&#xff0c;会话范围实现返回会话范围的bean&#xff08;如果它不存在&#xff0c;该方法在绑定到会话以供将来参考之后返回该bean的新实例&#xff09;。

Object get(String name, ObjectFactory objectFactory)

以下方法将该对象从基础范围中移除。例如&#xff0c;会话范围实现从基础会话中删除会话范围的bean。应该返回该对象&#xff0c;但如果找不到具有指定名称的对象&#xff0c;则可以返回null。

Object remove(String name)

以下方法注册范围在销毁时或范围内的指定对象被销毁时应执行的回调。有关销毁回调的更多信息&#xff0c;请参阅javadocs或Spring范围实现。

void registerDestructionCallback(String name, Runnable destructionCallback)

以下方法获取基础范围的对话标识符。这个标识符对于每个范围是不同的。对于会话范围的实现&#xff0c;这个标识符可以是会话标识符。

String getConversationId()

2 使用自定义范围

在你编写和测试一个或多个自定义Scope实现之后&#xff0c;你需要让Spring容器知道你的新的作用域。以下方法是Scope使用Spring容器注册新的核心方法&#xff1a;

void registerScope(String scopeName, Scope scope);

这个方法是在ConfigurableBeanFactory接口中声明的&#xff0c;该接口在ApplicationContextSpring通过BeanFactory属性提供的大多数具体实现中都可用。
该registerScope(..)方法的第一个参数是与范围关联的唯一名称; Spring容器本身的这些名字的例子是singleton和 prototype。该registerScope(..)方法的第二个参数是Scope您希望注册和使用的自定义实现的实际实例。

假设你编写你的自定义Scope实现&#xff0c;然后如下注册它。

下面的例子使用了SimpleThreadScope&#xff0c;这个已经被Spring包括了&#xff0c;但是默认是没有注册的。这些说明对您自己的自定义Scope 实现而言是相同的。

Scope threadScope &#61; new SimpleThreadScope();
beanFactory.registerScope("thread", threadScope);

然后创建符合自定义的范围规则的bean定义Scope&#xff1a;

"..." class&#61;"..." scope&#61;"thread">

通过自定义Scope实现&#xff0c;您不限于对范围进行程序化注册。您也可以Scope使用CustomScopeConfigurer该类以声明方式进行注册 &#xff1a;


<beans xmlns&#61;"http://www.springframework.org/schema/beans"xmlns:xsi&#61;"http://www.w3.org/2001/XMLSchema-instance"xmlns:aop&#61;"http://www.springframework.org/schema/aop"xsi:schemaLocation&#61;"http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><bean class&#61;"org.springframework.beans.factory.config.CustomScopeConfigurer"><property name&#61;"scopes"><map><entry key&#61;"thread"><bean class&#61;"org.springframework.context.support.SimpleThreadScope"/>entry>map>property>bean><bean id&#61;"bar" class&#61;"x.y.Bar" scope&#61;"thread"><property name&#61;"name" value&#61;"Rick"/><aop:scoped-proxy/>bean><bean id&#61;"foo" class&#61;"x.y.Foo"><property name&#61;"bar" ref&#61;"bar"/>bean>beans>

放置&#96;在FactoryBean实现中时&#xff0c;它是工厂bean本身的作用域&#xff0c;而不是从中返回的对象getObject()。
好啦&#xff0c;这一节的细节到这里就结束啦。




推荐阅读
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • Imtryingtofigureoutawaytogeneratetorrentfilesfromabucket,usingtheAWSSDKforGo.我正 ... [详细]
  • Asp.net Mvc Framework 七 (Filter及其执行顺序) 的应用示例
    本文介绍了在Asp.net Mvc中应用Filter功能进行登录判断、用户权限控制、输出缓存、防盗链、防蜘蛛、本地化设置等操作的示例,并解释了Filter的执行顺序。通过示例代码,详细说明了如何使用Filter来实现这些功能。 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • 本文讨论了如何在codeigniter中识别来自angularjs的请求,并提供了两种方法的代码示例。作者尝试了$this->input->is_ajax_request()和自定义函数is_ajax(),但都没有成功。最后,作者展示了一个ajax请求的示例代码。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 网络请求模块选择——axios框架的基本使用和封装
    本文介绍了选择网络请求模块axios的原因,以及axios框架的基本使用和封装方法。包括发送并发请求的演示,全局配置的设置,创建axios实例的方法,拦截器的使用,以及如何封装和请求响应劫持等内容。 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • Hibernate延迟加载深入分析-集合属性的延迟加载策略
    本文深入分析了Hibernate延迟加载的机制,特别是集合属性的延迟加载策略。通过延迟加载,可以降低系统的内存开销,提高Hibernate的运行性能。对于集合属性,推荐使用延迟加载策略,即在系统需要使用集合属性时才从数据库装载关联的数据,避免一次加载所有集合属性导致性能下降。 ... [详细]
  • LVS实现负载均衡的原理LVS负载均衡负载均衡集群是LoadBalance集群。是一种将网络上的访问流量分布于各个节点,以降低服务器压力,更好的向客户端 ... [详细]
author-avatar
mobiledu2502894115
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有