Spring-对象的生命周期和作用域

目录

Bean的作用域

作用域

设置作用域

 Spring的执行流程和Bean的生命周期

Bean的生命周期


Bean的作用域

BeanApplication类会将一个User对象注册进入Spring 

@Controller
public class BeanApplication {
    @Bean(name = "user")
    public User init() {
        User user = new User();
        user.setName("李四");
        return user;
    }
}

 UserApplication类对从框架中获取到的User对象进行修改

@Controller
public class UserApplication {
    @Autowired
    private User user;//这里会获取到Spring内的一个 User对象

    public void getUser() {
        User user1 = user;
        System.out.println("原来的 user " + user1);
        user1.setName("孙悟空");
    
    }
}

 Text类会从框架中拿到User对象,进行打印

@Controller
public class Text {
    @Autowired
    private User user;

    public void print() {
        System.out.println("user :->" + user);
    }
}

按照我们的预期, UserApplication只是应该修改自己的代码,不应该让这个修改作用于框架内的User对象

产生这个问题的原因是,Spring默认使用单例模式

作用域

Bean对象的作用域就是对象的作用范围

Spring框架的Bean对象有6种

前两种是普通spring项目中的,后四个是Spring MVC的值

1、singleton:单例作用域(默认单例模式)

2、prototype:原型作用域(多例模式)

3、request:请求作用域

4、session:回话作用域

5、application:全局作用域

6、websocket:HTTP WebSocket作用域

作用范围描述
singleton默认值,单例模式,表示在 Spring 容器中只有一个 Bean 实例
prototype原型模式,表示每次通过 Spring 容器获取 Bean 时,容器都会创建一个新的 Bean 实例。
request每次 HTTP 请求,容器都会创建一个 Bean 实例。该作用域只在当前 HTTP Request 内有效。
session同一个 HTTP Session 共享一个 Bean 实例,不同的 Session 使用不同的 Bean 实例。该作用域仅在当前 HTTP Session 内有效。
application同一个 Web 应用共享一个 Bean 实例,该作用域在当前 ServletContext 内有效。

与 singleton 类似,但 singleton 表示每个 IoC 容器中仅有一个 Bean 实例,而一个 Web 应用中可能会存在多个 IoC 容器,但一个 Web 应用只会有一个 ServletContext,也可以说 application 才是 Web 应用中货真价实的单例模式。
websocketwebsocket 的作用域是 WebSocket ,即在整个 WebSocket 中有效。

设置作用域

在对象存入框架之前,使用Scope注解设置对象的作用域

除了自己传入参数, 还有一种是使用提供的常量设置

 Spring的执行流程和Bean的生命周期

执行流程:1、启动容器2、加载配置文件3、创建Bean对象4、Bean对象注册到容器(存对象)5、Bean对象装配到其他类(取对象) 

Bean的生命周期

对象的生命周期就是对象创建和删除的过程

1、实例化Bean对象(分配内存)

2、设置属性(Bean注入和装配)

3、Bean初始化

  • 执行各种Aware通知的方法,例如生成BeanName的BeanNameAware接口方法

  • 若容器中有BeanPostProcessor,则调用,执行初始化前置方法

  • 执行构造方法,有两种形式:@PostConstruct初始化构造,另一种是执行指定了Bean的init-method方法(在配置文件设置)如果两个都有,注解优先执行

  • 执行初始化的后置方法 BeanPostProcessor

4、使用Bean

5、销毁Bean:可以有三种方法,@PreDestory、DisposableBean接口方法,destory-method

Bean创建过程中的“实例化”与“初始化”名词

  • 实例化(Instantiation): 要生成对象, 对象还未生成.
  • 初始化(Initialization): 对象已经生成.,赋值操作。

BeanPostProcessor :
发生在 BeanDefiniton 加工Bean 阶段. 具有拦截器的含义. 可以拦截BeanDefinition创建Bean的过程, 然后插入拦截方法,做扩展工作

postProcessBeforeInitialization初始化前置处理 (对象已经生成)
postProcessAfterInitialization初始化后置处理 (对象已经生成)

 我们使用代码,检验上述过程

1、在Text包下,创建PostProcessor类,实现BeanPostProcessor接口,实现接口中的postProcessBeforeInitialization,postProcessAfterInitialization方法

@Controller
public class PostProcessor implements BeanPostProcessor {

    @Override

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("对象" + beanName + "开始实例化");
        return bean;
    }

    @Override

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        System.out.println("对象" + beanName + "实例化完成");
        return bean;
    }
}

2、创建类BeanLife

public class BeanLife implements BeanNameAware {
    //1、执行通知
    @Override
    public void setBeanName(String s) {
        System.out.println("执行了BeanName这个通知方法 beanName=" + s);
    }

    //3、执行构造方法
    @PostConstruct
    public void Construct() {
        System.out.println("执行PostConstruct构造方法");
    }

    //4、有两个构造方法 先执行上一个
    public void init() {
        System.out.println("执行init-method指定的方法");
    }
    //5、执行初始化的后置方法

    //6、销毁
    @PreDestroy
    public void destory() {

        System.out.println("执行 PreDestroy 方法");
    }

}

3、配置文件信息如下:

 4、测试类

public class App {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        PostProcessor postProcessor=context.getBean(PostProcessor.class);
        BeanLife life=context.getBean(BeanLife.class);
        context.destroy();
    }
}

 ApplicationContext会自动检测在配置文件中实现了BeanPostProcessor接口的所有bean,并把它们注册为后置处理器,然后在容器创建bean的适当时候调用它

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值