Bean的作用域和生命周期

期进springboot

目录

1.Bean的作用域

               1.1Bean的六大作用域

               1.2设置Bean的作用域

2.Bean的执行流程

3.Bean的生命周期


1.Bean的作用域

①什么是Bean的作用域:

实质上是指Bean在spring整个框架中的某种行为模式,比如singleton单例模式,就是指Bean在整个作用域中只有一份,并且是全局共享的,当其他人在任意处修改了,那么其他人读到的就是修改后的数据。

②对①中进行示例:

(大概思路就是通过公共Bean部分来对原值进行设置,然后我们用A用户对其实行修改,并接着用B用户去进行获取,看得到的值是否一致)

(1)公共Bean的部分(我们将公共bean设置于此)

package inBean;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class Users {
    @Bean
    public User user1(){
        User user=new User();
        user.setName("张三");
        user.setId(1);
        return user;
    }
}

(2)A用户对原来数据进行修改:

package inBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
@Controller
public class UserController4 {
    @Autowired
    private User user1;
    public User getUser(){
        User user=user1;
        System.out.println("修改前的名称+ID"+user.getName()+user.getId());
        user.setId(2);
        user.setName("李四");
        return user;
    }
}

(3)B用户对修改后的数据来进行获取:

package inBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController3 {
  @Autowired
    private User user1;
  public User getUser1(){
      User user=user1;
      return  user;
  }
}

(4)main:

import inBean.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
        public static void main(String[] args) {
            //1.先获取对象的上下文
            ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
            //方式一
           UserController4 userController4=context.getBean("userController4",UserController4.class);
            System.out.println("A修改后的对象"+userController4.getUser().toString());
            UserController3 userController3=context.getBean("userController3",UserController3.class);
            System.out.println(userController3.getUser1());
        }
    }

输出结果:

我们在这里看到修改前的名字+ID分别为张三 1,但是当A用户进行修改后,B用户去获取到的值也是修改后的值。这是为什么呢?

这是因为spring中bean的默认情况下是单例模式,也就是修改后所有其他的读取到的都是修改后的值。 

               1.1Bean的六大作用域

①singleton:单例作用域(默认)

通常无状态(bean的状态不需要修改)下的bean就会使用该作用域,而且每一次注入的bean都是同一个bean。并且这是一种默认状态
②prototype:原型作用域(多例作用域)

原例模式实质上就是类似于多例模式,每次对该作用域下的Bean时,就会创建出新的实例。
③request:请求作用域(Spring MVC)

每次HTTP请求时就会创建出新的实例,一次HTTP请求和响应共用Bean,限于在spring MVC中使用。
④session:会话作用域(Spring MVC)

在用户会话的时候共享bean,举个例子,在你登录某个APP时,你的登录信息会被存储起来,这个时候就相当于在你登录期间,一直是在共享bean。
⑤application:全局作用域(Spring MVC)

这是关于web的上下文信息,只需了解即可。
⑥websocket: HTTP WebSocket 作用域(Spring WebSocket)

只需了解即可。

               1.2设置Bean的作用域

①直接设置:

(1)方法:

使用@Scope(“prototype”),直接将其加在Bean下即可。

(2)演示:前面我们演示了默认情况下是单例模式,此时,我们就在该单例模式的基础上来实现这个@Scope(“prototype”),使其可以成为多例模式,即修改后并不影响原来的值。

②使用枚举设置:

(这里的枚举设置并不是说真的就是枚举,只是类似于这种形式罢了) 

(1)方法:(这个的优势在于不容易输错)

@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

(2)演示:(仍然是以上面这个例子来进行修改)

实现的是和①中同样的效果,只是方法里面参数不同罢了。 

2.Bean的执行流程

①简单叙述:

当我们启动容器的时候,执行main函数时,首先会对Application中的类加载路径进行加载(spring-config.xml),紧接着会根据该xml文件中的配置扫描找到对应的包,找到对应的包后,就会开始扫描里面的spring注解,然后将Bean对象注册到容器中,这个时候如果bean对象有其他属性,也会进行读取。

②图例展示:

3.Bean的生命周期

Bean的生命周期主要分为5大过程,这里我们简单地对这五大过程进行讲解。

①实例化Bean:(买房)

实质上就是为bean分配内存空间

②设置属性:(装修)

就是指的是bean注入和配置

③Bean的初始化:(购置家具)

a.执行各种通知(执行各种 Aware) 
b. 执行初始化的前置方法;
c. 执行构造方法,两种执行方式,一种是执行@PostConstruct,另一种实质性 init-method;
d. 执行初始化的后置方法;

④使用Bean(入住)

⑤销毁bean:(卖房)

a.@PreDestory
b. 重写DisposableBean接口方法
c.destroy-method

下面我们来用代码证实一下确实经过了这些过程:

import org.springframework.beans.factory.BeanNameAware;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Component
public class BeanLifeComponent implements BeanNameAware {
    @PostConstruct
    public void postConstruct() {
        System.out.println("执行 @PostConstruct");
    }

    public void init() {
        System.out.println("执行 init-method");
    }

    public void use() {
        System.out.println("使用 bean");
    }


    @PreDestroy
    public void preDestroy() {
        System.out.println("执行了 @PreDestroy");
    }

    public void setBeanName(String s) {
        System.out.println("执行了 Aware 通知");
    }
}
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
        public static void main(String[] args) {
            ClassPathXmlApplicationContext context =
                    new ClassPathXmlApplicationContext("spring-config.xml");
            BeanLifeComponent beanLifeComponent = context.getBean("beanLifeComponent",BeanLifeComponent.class);
            beanLifeComponent.use();
            context.destroy();
        }
    }

输出结果:

下期我们将讲解springboot相关内容~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张洋洋~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值