Java?Spring中Bean的作用域及生命周期_java

来源:脚本之家  责任编辑:小易  
目录
1.Bean的作用域1.1 被修改的Bean案例1.2 为什么使用单例模式作为默认作用域1.3 作用域1.4 Bean的6种作用域1.5 设置作用域2.Spring执行流程和Bean的生命周期2.1 Bean的生命周期2.1.1生命周期演示2.1.2 为什么要先设置属性,在进行初始化

1.Bean的作用域

1.1 被修改的Bean案例

原因:Bean的作用域默认是单例模式的,也就是说所有?的使?的都是同?个对象!之前我们学单例模式的时候都知道,使?单例可以很?程度上提?性能,所以在 Spring 中Bean 的作?域默认也是 singleton 单例模式。

@Component
public class Users {

    @Bean
    public User user1(){
        User user = new User();
        user.setId(1);
        user.setName("Java");
        return user;
    }
}
@Component
public class Bean1 {

    @Autowired
    private User user;
    public User getUser(){
        System.out.println("Bean1对象未修改name之前 : "+user);
        user.setName("C++");
        return user;
    }
}
@Component
public class Bean2 {
    @Autowired
    private User user;

    public User getUser(){
        return user;
    }
}
public class App {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");

        Bean1 bean1 = context.getBean("bean1",Bean1.class);
        System.out.println(bean1.getUser());
        Bean2 bean2 = context.getBean("bean2",Bean2.class);
        System.out.println(bean2.getUser());
    }
}

1.2 为什么使用单例模式作为默认作用域

相同资源只创建一份,节省空间不需要过多的创建和销毁对象,执行速度提高

1.3 作用域

作用域,一般理解为:限定程序中变量的可?范围叫做作?域,或者说在源代码中定义变量的某个区域就叫做作?域。
?Bea的作?域是指BeanSpring整个框架中的某种?为模式,?如singleton单例作?域,就表
Bean在整个Spring中只有?份,它是全局共享的,那么当其他?修改了这个值之后,那么另?个
?读取到的就是被修改的值。

在Spring中,bean 的作用域被称为是行为模式,因为在Spring看来,单例模式,就是一种行为,意味着在整个Spring中bean只能存在一份。

1.4 Bean的6种作用域

singleton:单例作?域prototype:原型作?域(多例作?域)request:请求作?域session:会话作?域application:全局作?域websocket:HTTP WebSocket 作?域

后四种都是SpringMVC中限定使用的,因此现阶段我们只学前两个就行。

1.5 设置作用域

回到刚才的案例,Bean2希望获取到的bean对象是未被修改的,我们就可以将单例模式修改为多例模式。

使用@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

使用@Scope("prototype")

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

ps:当执行性到装配Bean的属性那一步时,当扫描到有属性注入时,会先停下类注入,优先进行属性注入,因为后面的方法可能会用到该属性。

2.1 Bean的生命周期

所谓的生命周期指的是一个对象从诞生到销毁的整个生命过程,我们把这个过程就叫做一个对象的生命周期。

Bean 的生命周期分为以下5大部分:

1.实例化 Bean(为 Bean 分配内存空间)2.设置属性(Bean 注入和装配)3.Bean 初始化
实现了各种 Aware 通知的方法,如 BeanNameAware、BeanFactoryAware、 ApplicationContextAware 的接口方法,例如:Spring在初始化 bean,是需要给 bean 赋予 id(name)。而设置 beanName 成功的话,就会生成一个 beadNameAware 通知;执行 BeanPostProcessor 初始化前置方法(如果没有重写此方法,按照源码操作);执行 @PostConstruct 初始化方法,依赖注入操作之后被 执行;执行自己指定的 init-method 方法(如果有指定的话),是Spring中bean标签内指定的方法;

这个初始化方法和上面一个用注解初始化的方法是两个不同时期的产物,init是xml时代产物,@PostConstruct是注解时代产物。优先级:当梁总方法同时存在时,优先执行注解,再执行init执行 BeanPostProcessor 初始化后置方法(如果没有重写此方法,按照源码操作)。
4.使用 Bean5.销毁 Bean销毁容器的各种方法, 如 @PreDestroy、DisposableBean 接口方法、destroy-method。

@PreDestroy和destroy-method的关系和初始化方法的两个关系差不多
优先级:@ProDestroy > 重写的DisposableBean接口方法 > destroy-method

执行流程图如下:

ps:实例化和初始化的区别:实例化就是 分配内存空间。初始化,就是把我们一些参数,方法的具体实现逻辑给加载进去。

2.1.1生命周期演示

xml配置如下:

Bean

public class BeanLifeComponent implements BeanNameAware {
    @PostConstruct
    public void PostConstruct(){
        System.out.println("执行@PostConstruct");
    }
    public void init(){
        System.out.println("执行bean-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通知");
    }
}

启动类

public class App2 {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        BeanLifeComponent beanLifeComponent = context.getBean(BeanLifeComponent.class);
        beanLifeComponent.use();
        context.destroy();
    }
}

xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:content="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <content:component-scan base-package="com.beans"></content:component-scan>
    <bean id="1" class="com.beans.BeanLifeComponent" init-method="init"></bean>
</beans>

2.1.2 为什么要先设置属性,在进行初始化

@Controller
public class TestUser {
    @Autowired
    private Test test;

    public TestUser(){
        test.sayHi();
        System.out.println("TestUser->调用构造方法");
    }
}

如果这段代码先执行了初始化,也就是其构造方法,会用到test对象,此时还没有设置属性,test就为null,会造成空指针异常。因此必须先设置属性,在进行初始化。

到此这篇关于Java Spring中Bean的作用域及生命周期的文章就介绍到这了,更多相关Java Spring Bean 内容请搜索真格学网以前的文章或继续浏览下面的相关文章希望大家以后多多支持真格学网!

您可能感兴趣的文章:Spring Bean作用域与生命周期深入讲解一文搞懂Spring Bean中的作用域和生命周期SpringIOC容器Bean的作用域及生命周期实例详解Spring中Bean的作用域与生命周期Spring中Bean的作用域与生命周期详解SPRING FRAMEWORK BEAN作用域和生命周期原理解析深入了解Spring中Bean的作用域和生命周期浅谈Spring中Bean的作用域、生命周期详解Spring中Bean的生命周期和作用域及实现方式

  • 本文相关:
  • mybatis-plus动态表名实现方法
  • springcloud集成zookeeper实现服务注册并访问功能
  • 举例讲解java中do-while语句的使用方法
  • 拦截器获取request的值之后,controller拿不到值的解决
  • java线程的并发工具类实现原理解析
  • java并发编程之concurrentlinkedqueue源码详解
  • 剑指offer之java算法习题精讲二叉树与链表
  • spring mvc4.1.6 spring4.1.6 hibernate4.3.11 mysql5.5.25开发环境搭
  • java并发编程之死锁相关知识整理
  • 使用java web 在jsp文件及class中连接mysql和sqlserver 的驱动方法
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全c#教程vbvb.netc 语言java编程delphijavaandroidiosswiftscala易语言汇编语言r语言其它相关首页javaspring bean作用域与生命周期深入讲解一文搞懂spring bean中的作用域和生命周期springioc容器bean的作用域及生命周期实例详解spring中bean的作用域与生命周期spring中bean的作用域与生命周期详解spring framework bean作用域和生命周期原理解析深入了解spring中bean的作用域和生命周期浅谈spring中bean的作用域、生命周期详解spring中bean的生命周期和作用域及实现方式mybatis-plus动态表名实现方法springcloud集成zookeeper实现服务注册并访问功能举例讲解java中do-while语句的使用方法拦截器获取request的值之后,controller拿不到值的解决java线程的并发工具类实现原理解析java并发编程之concurrentlinkedqueue源码详解剑指offer之java算法习题精讲二叉树与链表spring mvc4.1.6 spring4.1.6 hibernate4.3.11 mysql5.5.25开发环境搭java并发编程之死锁相关知识整理使用java web 在jsp文件及class中连接mysql和sqlserver 的驱动方法intellij idea 2020最新intellij?idea?2020.2.3永久破解激活java使double保留两位小数的多方法 java保留两位idea2021.2永久激活码最新超详细(激活到2099)idea 2020版本最新破解教程可激活至2089java8 十大新特性详解2020.2 intellij ideajava.net.socketexception: connidea?2020.3最新永久激活码(免费激活到?209java写入文件的几种方法分享java回调机制实例详解在maven中引入本地jar包的步骤基于spring?boot的线程池监控问题及解决方案springboot中的main方法注入service浅谈java向下转型的意义java中decimalformat用法详解从零开始在centos7上部署springboot项目java实现微信退款功能springboot与quartz集成实现分布式定时任务集群的代码实例java微信企业号开发之开发模式的开启
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved