Spring的一些思考(一)

new一个对象和依赖注入一个对象的区别?

  • new一个对象时,直接使用关键字new来创建实例。这个对象的生命周期由自己来管理,可以实现对对象的细粒度的控制
  • 依赖注入是创建对象的另一种方式。DI可以减轻耦合,生命周期由Spring来负责,只需配置该对象和它依赖的对象如何配置即可
  • DI的优势
    • 解耦:对象间的关系在运行时自动建立
    • 集中化管理:所有的对象都由DI统一管理
    • 可配置性和模块化:配置文件可以改变某个对象的具体实现
  • 特别的,对于状态会改变的对象或者生命周期很短的对象使用new

DI每次注入的都是同一个对象吗?

依赖注入框架(如Spring)的行为取决于你如何配置你的Bean。特别地,一个由Spring管理的bean的生命周期范围(或"作用域")可以是以下几种类型之一:

  1. 单例(Singleton):默认情况下,Spring容器只会为每个被标记为@Component@Service的类创建一个实例,所有对该类型对象的注入都会得到相同的实例。这种作用域被称为单例作用域。
  2. 原型(Prototype):如果你配置Bean的作用域为"prototype",那么每次注入Bean时,Spring都会创建一个新的实例。
  3. 请求(Request):每次HTTP请求都会创建一个新的Bean,适用于Web应用。
  4. 会话(Session):同一个HTTP Session共享一个Bean,适用于Web应用。
  5. 全局会话(Global Session):一般用在Portlet环境,所有的Portlet共享一个Bean。

​ 所以,依赖注入的Bean是不是每次都相同,实际上取决于你如何配置它的作用域。在大多数情况下,你可能想要将大部分的Bean配置为单例,因为在单一的Spring服务容器中重复使用同一个Bean实例通常是安全的。但在某些特殊情况下,如Web应用或者带有状态的Bean,你可能会需要不同的作用域。


如何修改Bean的作用域呢?

在Spring框架中,有两种主要的方式可以设置Bean的作用域:使用XML配置文件或者注解。

使用XML配置文件设置Bean的作用域:

  1. 在Spring XML配置文件中,你可以使用<bean>元素的scope属性来设置Bean的作用域。
    <!-- 单例作用域 -->
    <bean id="singletonBean" class="com.example.ExampleClass" scope="singleton" />

    <!-- 原型作用域 -->
    <bean id="prototypeBean" class="com.example.ExampleClass" scope="prototype" />

    <!-- Web相关作用域 -->
    <!--<bean id="requestBean" class="com.example.ExampleClass" scope="request" />-->
    <!--<bean id="sessionBean" class="com.example.ExampleClass" scope="session" />-->
    <!--<bean id="globalSessionBean" class="com.example.ExampleClass" scope="globalSession" />-->

使用注解设置Bean的作用域

  1. 在Spring 3.0及更高版本中,你也可以使用@Scope注解来设置Bean的作用域。
@Component
@Scope("singleton")
public class SingletonBean {
    // ...
}

@Component
@Scope("prototype")
public class PrototypeBean {
    // ...
}

// 对于Web作用域,你需要指定一个额外的注解@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
/*@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestBean {
    // ...
}

@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class SessionBean {
    // ...
}
*/

注意,对于Web作用域(request、session、globalSession),你需要添加proxyMode属性,因为在一些情况下,Spring需要创建一个代理类来确保在整个请求或者会话中都能获取同一个Bean。

以上示例设置了不同的作用域,singleton表示单例,当你的应用启动时,Spring会立即实例化一个此类的Bean;prototype表示原型,每次注入或者通过Spring的ApplicationContext获取的时候,都会创建新的Bean实例。了解这些不同的作用域可以帮助你更好地管理你的Bean的生命周期。


默认情况下是Singleton?

  1. 在Spring框架里,Bean的默认作用域是单例(Singleton)。这意味着Spring容器在每个ApplicationContext中,对于每一个特定的Bean定义,都只会实例化一个对象。
  2. 无论一个单例作用域的Bean被注入到其他Bean多少次或者通过ApplicationContext直接获取多少次,所有地方拿到的都会是同一个对象实例。这种方式的好处是可以进行全局的控制和全局的状态分享,比如全局的配置类就比较适合设置为单例模式。
    当然,如果需要,可以通过设置@Scope注解或者在XML配置评论中特别指定,以改变Bean的作用域。

bean存放在applicationcontext中?

  1. 在Spring框架中,所有被Spring管理的Bean都会被存储在一个名为ApplicationContext的上下文对象中。ApplicationContext可以被视为一个大容器,它负责实例化、配置和装配Bean。
  2. Spring框架提供了多种类型的ApplicationContext实现,分别适用于不同的环境和需求。例如,对于Web应用,通常会使用WebApplicationContext
  3. 在ApplicationContext中,Bean由其名称和定义唯一标识。在整个ApplicationContext中,Bean的ID或名字必须是唯一的。在创建ApplicationContext时,Spring会根据每个Bean的定义来创建对象,并将这些对象存入ApplicationContext中。
  4. 在应用运行过程中,当需要用到某个Bean时,可以通过ApplicationContext来获取。例如,如果在Spring中使用依赖注入,Spring会在ApplicationContext中查找相关的Bean来注入。

不过需要注意的是,ApplicationContext并不直接管理Bean的生命周期,Bean的创建和销毁是由Spring的IoC(控制反转)容器管理的,ApplicationContext则负责提供从名称、类型或者其他标准查找和获取Bean的方式。


ApplicationContext与ServletContext?

ApplicationContext与ServletContext是两种不同的概念,它们在Spring web应用中都有使用,但是各自的用途不同。

  • ServletContext:这是Java web应用中的一个接口,在一个web应用中只存在一个ServletContext实例,它代表当前web应用。ServletContext主要用于访问web应用的各种资源,获取web应用的初始化参数,进行日志记录,获取web应用的各个部分如Servlet,共享数据等。
  • ApplicationContext:这是Spring中的一个接口,是Spring的IoC容器,负责实例化、定位、配置应用程序中的对象和建立这些对象间的依赖。ApplicationContext在一个Spring application中也是唯一的。对于Spring Web应用,会有专门的WebApplicationContext,这个WebApplicationContext是和每一个Servlet关联的。

它们之间的关系是:在Spring Web应用中,Spring会为每一个Servlet创建一个WebApplicationContext,并且这个WebApplicationContext可以访问到ServletContext。也就是说,ServletContext是Java Web应用的范畴,而Spring的ApplicationContext(特别是WebApplicationContext)存在于ServletContext之中,管理Spring应用中的Bean。

所以说,ServletContext和ApplicationContext是分别存在于Java EE Web层和Spring框架层的两个不同的上下文概念,是两个层面的容器。


在Java Web应用中,ServletContext和Spring的ApplicationContext(特别的WebApplicationContext)确实存在一种包含关系,但它们是在两种不同的层面上:

  1. ServletContext是属于Servlet API,在整个Web应用中,只有一个ServletContext实例存在,它作为Web应用的上下文,代表了当前的Web应用。它是Java EE Web层的容器。
  2. 属于Spring框架的ApplicationContext(在Web环境中是WebApplicationContext)则是在ServletContext之中。对于Spring Web应用,Spring会为每一个Servlet创建一个WebApplicationContext。这个内部的WebApplicationContext是一个Spring的IoC容器,它管理这个特定Servlet内部的Bean。

所以,ServletContext包含了WebApplicationContext,可以理解成整个Web应用上下文(ServletContext)中包含了各自Servlet的上下文(WebApplicationContext)。

这是一个父子关系,WebApplicationContext可以访问ServletContext中的所有资源,而ServletContext不能访问WebApplicationContext。在一个Spring MVC应用中,通常以WebApplicationContext作为主要的工作区,进行各种数据处理和逻辑运算。

  • 19
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值