Spring--Bean的作用域,生命周期

Bean的作用域

Bean的作用域有很多种,在Spring Framework中支持6种(其中有四种只有在web环境中才能生效),同时Spring还支持自定义Bean的范围。

Spring Framework中支持的6种范围:

作用域解释
singleton每个Spring IoC容器内同名称的bean只有一个实例(默认)
prototype

每次使用该bean时会创建新的实例

request每个HTTP请求生命周期内,创建新的实例(web环境中)
session每个HTTP Session生命周期内,创建新的实例(web环境中)
application每个ServletContext生命周期内,创建新的实例(web环境中)
websocket每个WebSocket生命周期内,创建新的实例(Web环境中)

如果想要更改 Bean 的作用域应该如何进行设置呢?

@Scope

我们可以通过修改@Scope注解中的value属性的值来修改Bean的作用域。

singleton

当我们直接在Spring中定义一个Bean时此时它默认的作用域是 singleton(单例)。

此时先定义一个类,然后将它交给Spring管理:

public class Dog {
    public String name;

    public Dog(){};

    public Dog(String name){
        this.name = name;
    }
}
@Component
public class Demo {
    @Bean
    public Dog dog() {
        Dog dog = new Dog();
        return dog;
    }
}

此时我们通过ApplicationContext对象来从容器中分两次拿取,看两次拿取的类是否相同。

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        //获取Spring的上下文
        ApplicationContext context = SpringApplication.run(Application.class, args);
        Object dog1 = context.getBean("dog");
        Object dog2 = context.getBean("dog");
        System.out.println(dog1);
        System.out.println(dog2);
    }
}

从打印的结果中我们可以看出dog1和dog2这两个对象是相同的。

prototype

将Bean作用域修改为 prototype 之后再进行打印观察,通过结果可以看出是两个不同的对象:

@Component
public class Demo {
    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public Dog dog() {
        Dog dog = new Dog();
        return dog;
    }
}

注意:request,session,application,websocket这四中作用域下的Bean只能再Web环境中获取,否则会报如下异常:

在web环境中获取Bean对象:

@RestController
@RequestMapping("/bean")
public class BeanController {
    @Autowired
    private Dog dog1;
    @Autowired
    private Dog dog2;

    @RequestMapping("/fun")
    public String test() {
        return "<p>"+dog1.toString()+"</p><p>"+dog2.toString()+"</p>";
    }
}

@RequestScope

被该注解修饰表示该Bean的作用域是 request 。

@Component
public class Demo {
    @Bean
    @RequestScope
    public Dog dog() {
        Dog dog = new Dog();
        return dog;
    }
}

当通过浏览器获取结果是发现这两个Bean是相同的,但是如果再刷新一下浏览器就会发现两次访问获取的结果不同:

@SessionScope

被该注解修饰表示该Bean的作用域为 session 。

@Component
public class Demo {
    @Bean
    @SessionScope
    public Dog dog() {
        Dog dog = new Dog();
        return dog;
    }
}

此时通过浏览器获取结果,可以从结果中得知同一个浏览器的结果相同,不同浏览器结果不同。 

@ApplicationScope

该注解表示被修饰地Bean的作用域为 application 。

@Component
public class Demo {
    @Bean
    @ApplicationScope
    public Dog dog() {
        Dog dog = new Dog();
        return dog;
    }
}

Application scope就是对于整个web容器来说,bean的作用域是ServletContext级别的。这个和
singleton有点类似,区别在于:Application scope是ServletContext的单例,singleton是一个
ApplicationContext的单例,在⼀个web容器中ApplicationContext可以有多个。

Bean的生命周期

Bean的生命周期指的是Bean对象从创建直到销毁的全过程。

Bean的生命周期大致可以分为以下5步:

实例化(为Bean对象分配内存空间);

属性赋值(Bean注入或装配,如@AutoWired);

初始化;

  • 执行各种通知,如 BeanNameAware, BeanFactoryAware ,ApplicationContextAware 的接口方法
  • 执行初始化方法:
  1. xml定义 init-method
  2. 使用注解的方式 @PostConstruct
  3. 执行初始化后置方法(BeanPostProcessor )

使用Bean;

销毁Bean。

光这么看有点抽象,下面用代码展示一下:

@Slf4j
@Component
public class Animal {
    public Dog dog;
    //实例化
    public Animal() {
        log.info("执行构造方法");
    }
    //属性注入
    @Autowired
    public void setDog(Dog dog) {
        this.dog = dog;
        log.info("属性注入");
    }
    //初始化
    @PostConstruct
    public void init() {
        log.info("执行初始化方法");
    }
    //使用
    public void use() {
        log.info("use");
    }
    //销毁
    @PreDestroy
    public void destroy() {
        log.info("执行destroy方法");
    }
}

接下来执行这个类中的use()方法,然后观察打印结果:

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        //获取Spring的上下文
        ApplicationContext context = SpringApplication.run(Application.class, args);
        Animal animal = (Animal) context.getBean("animal");
        animal.use();
    }
}

  • 61
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 27
    评论
Spring Bean 的作用域生命周期Spring 框架中非常重要的两个概念,这里简单介绍一下。 1. Bean 的作用域Spring 中,Bean 的作用域指的是 Bean 实例的创建和销毁的范围。Spring 提供了以下五种作用域: - singleton:单例模式,容器中只有一个 Bean 实例,所有对 Bean 的请求都将返回同一个实例。 - prototype:每次请求都会创建一个新的 Bean 实例。 - request:每个 HTTP 请求都会创建一个新的 Bean 实例。 - session:每个 HTTP Session 都会创建一个新的 Bean 实例。 - global session:基于 Servlet 3.0+ 的环境下,每个全局的 HTTP Session 都会创建一个新的 Bean 实例。 2. Bean 的生命周期 Bean 的生命周期指的是 Bean 实例从创建到销毁的整个过程。Spring 提供了以下七个阶段: - 实例化 Bean:Spring 根据 Bean 的定义创建一个 Bean 的实例。 - 设置 Bean 属性:Spring 将配置文件中的属性设置到 Bean 实例中。 - BeanNameAware:如果 Bean 实现了 BeanNameAware 接口,SpringBean 的 ID 传递给 setBeanName 方法。 - BeanFactoryAware:如果 Bean 实现了 BeanFactoryAware 接口,SpringBeanFactory 实例传递给 setBeanFactory 方法。 - InitializingBean:如果 Bean 实现了 InitializingBean 接口,Spring 将调用 afterPropertiesSet 方法。 - 自定义初始化方法:Bean 可以配置自定义的初始化方法。 - DisposableBean:如果 Bean 实现了 DisposableBean 接口,Spring 将调用 destroy 方法。 - 自定义销毁方法:Bean 可以配置自定义的销毁方法。 以上就是 Spring Bean 的作用域生命周期的简单介绍。理解 Bean 的作用域生命周期对于正确使用 Spring 框架非常重要。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值