SpringBoot深入学习二

本文深入探讨了Spring框架中Bean的生命周期,包括初始化、销毁过程及自定义初始化和销毁方法。同时,详细讲解了Bean的作用域,如singleton、prototype等,并展示了如何使用@Scope注解来设置Bean的作用范围。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

@scope 申明bean的作用范围

1. 创建Car

public class Car {
	private String name;
	private int price;
	
	public Car(){
		System.out.println("car constructor...");
	}
}

2.将Car放入bean中管理

public class MainConfig {
    @Bean
    public Car car(){
        System.out.println("add bean car into spring");
        return new Car();
    }
}

3.启动spring容器

@Test
    public  void test04(){
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        System.out.println("IOC started");
     
    }

运行结果如下

因此spring注册组件默认是在创建IOC容器的时候创建的

将启动spring容器的代码中创建两个car

@Test
    public  void test04(){
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        System.out.println("IOC started");
        Car car1 = applicationContext.getBean(Car.class);
        Car car2 = applicationContext.getBean(Car.class);
        System.out.println(car1==car2);
    }

运行结果如下

因此,可知bean默认是单例的。在创建IOC容器的时候创建的,每当获取的时候都是同一个实例。

当在配置中添加@Lazy的时候,对相应的组件将会实行懒加载。调用的时候才会去实现初始化。

配置修改如下

public class MainConfig {

    @Bean
    @Lazy
    public Car car(){
        System.out.println("add bean car into spring");
        return new Car();
    }
}

运行结果如下

从结果可看出,懒加载的时候。调用时才回去加载bean。并且只加载一次。

spring有如下四种作用域

prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。
每次获取的时候才会调用方法创建对象;
singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。
以后每次获取就是直接从容器(map.get())中拿,
request:同一次请求创建一个实例
session:同一个session创建一个实例

可以用@Scope申明Bean的生命周期

修改配置成如下

public class MainConfig {

    @Scope("prototype")
    @Bean
    public Car car(){
        System.out.println("add bean car into spring");
        return new Car();
    }

再次运行

由结果可知。原型模式。spring初始化的时候并未去加载bean。而是在每次调用的时候再去加载。为多实例。

 

Spring bean的生命周期

bean的生命周期:bean创建—初始化----销毁的过程
容器管理bean的生命周期:我们可以自定义初始化和销毁方法;容器在bean进行到当>前生命周期的时候来调用我们自定义的初始化和销毁方法

1.指定初始化和销毁方法

在申明组件的时候,加上初始化和销毁的方法

public class Car  {
	private String name;
	private int price;
	
	public Car(){
		System.out.println("car constructor...");
	}
	
	public void init(){
		System.out.println("car ... init...");
	}
	
	public void destroy(){
		System.out.println("car ... destroy...");
	}

}

  通过@Bean指定init-method和destroy-method

public class MainConfig {
    @Bean(initMethod = "init",destroyMethod = "destroy")
    public Car car(){
        System.out.println("add bean car into spring");
        return new Car();
    }
}

开启和销毁容器

 @Test
    public  void test04(){
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        System.out.println("IOC started");
        Car car1 = applicationContext.getBean(Car.class);

        ((AnnotationConfigApplicationContext) applicationContext).close();
    }

运行结果如下图

由图可知:在组件创建的时候init方法被调用。在组件销毁的时候,destroy方法被调用。

当组件被申明为原型模式

public class MainConfig {

    @Scope("prototype")
    @Bean(initMethod = "init",destroyMethod = "destroy")
    public Car car(){
        System.out.println("add bean car into spring");
        return new Car();
    }

运行结果如下图所示

从结果可看出,如果bean是多实例,spring只负责创建Bean,在容器关闭时并不销毁bean。

实现InitializingBean(定义初始化逻辑) DisposableBean(定义销毁逻辑)

代码如下

public class Car implements InitializingBean, DisposableBean {
	private String name;
	private int price;
	
	public Car(){
		System.out.println("car constructor...");
	}
	
	@Override
	public void destroy(){
		System.out.println("car ... destroy...");
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println("car ... afterPropertiesSet...");

	}
}

运行结果如下

BeanPostProcessor

BeanPostProcessor,针对所有Spring上下文中所有的bean,配置一个BeanPostProcessor,然后对所有的bean进行一个初始化之前和之后的代理。BeanPostProcessor接口中有两个方法: postProcessBeforeInitialization和postProcessAfterInitialization。 postProcessBeforeInitialization方法在bean初始化之前执行, postProcessAfterInitialization方法在bean初始化之后执行。 

1.创建MyBeanPostProcessor继承BeanPostProcessor接口,重写postProcessBeforeInitialization和postProcessAfterInitialization两个方法。

public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("------------------------------");
        System.out.println("对象------" + beanName + "postProcessBeforeInitialization-----"+bean);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("------------------------------");
        System.out.println("对象-----" + beanName + "postProcessAfterInitialization-----"+bean);
        return bean;
    }
}

2.将MyBeanPostProcessor加入容器管理

@Configuration
public class MainConfig {
    @Bean(initMethod = "init",destroyMethod = "destroy")
    public Car car(){
        System.out.println("add bean car into spring");
        return new Car();
    }
    
    @Bean
    public MyBeanPostProcessor myBeanPostProcessor(){
        return new MyBeanPostProcessor();
    }
}

3.启动spring容器

   @Test
    public  void test04(){
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        System.out.println("IOC started");
        Car car1 = applicationContext.getBean(Car.class);

        ((AnnotationConfigApplicationContext) applicationContext).close();
    }

运行结果如下图

由结果可知:在每个bean的初始化前后都调用了BeanPostProcessor

Spring Boot 基础教程(基于1.3.x-1.5.x) 快速入门 chapter1:基本项目构建(可作为工程脚手架),引入web模块,完成一个简单的RESTful API 使用Intellij中的Spring Initializr来快速构建Spring Boot/Cloud工程 工程配置 chapter2-1-1:配置文件详解:自定义属性、随机数、多环境配置等 chapter2-1-2:2.0 新特性(一):配置绑定全解析 chapter2-2-1:2.0 新特性():新增事件ApplicationStartedEvent Web开发 chapter3-1-1:构建一个较为复杂的RESTful API以及单元测试 chapter3-1-2:使用Thymeleaf模板引擎渲染web视图 chapter3-1-3:使用Freemarker模板引擎渲染web视图 chapter3-1-4:使用Velocity模板引擎渲染web视图 chapter3-1-5:使用Swagger2构建RESTful API chapter3-1-6:统一异常处理 chapter3-1-7:使用Java 8中LocalDate等时间日期类的问题解决 chapter3-1-8:扩展XML请求和响应的支持 数据访问 chapter3-2-1:使用JdbcTemplate chapter3-2-2:使用Spring-data-jpa简化数据访问层(推荐) chapter3-2-3:多数据源配置(一):JdbcTemplate chapter3-2-4:多数据源配置():Spring-data-jpa chapter3-2-5:使用NoSQL数据库(一):Redis chapter3-2-6:使用NoSQL数据库():MongoDB chapter3-2-7:整合MyBatis chapter3-2-8:MyBatis注解配置详解 chapter3-2-9:使用Flyway来管理数据库版本 chapter3-2-10:使用LDAP来统一管理用户信息 chapter3-2-11:Spring Boot中增强对MongoDB的配置(连接池等) 事务管理 chapter3-3-1:使用事务管理 chapter3-3-2:[分布式事务(未完成)] 其他内容 chapter4-1-1:使用@Scheduled创建定时任务 chapter4-1-2:使用@Async实现异步调用 chapter4-1-3:使用@Async实现异步调用:自定义线程池 chapter4-1-4:使用@Async实现异步调用:资源优雅关闭 chapter4-1-5:使用@Async实现异步调用:使用Future以及定义超时 日志管理 chapter4-2-1:默认日志的配置 chapter4-2-2:使用log4j记录日志 chapter4-2-3:对log4j进行多环境不同日志级别的控制 chapter4-2-4:使用AOP统一处理Web请求日志 chapter4-2-5:使用log4j记录日志到MongoDB chapter4-2-6:Spring Boot 1.5.x新特性:动态修改日志级别] 安全管理 chapter4-3-1:使用Spring Security chapter4-3-2:[使用Spring Session(未完成)] 缓存支持 chapter4-4-1:注解配置与EhCache使用 chapter4-4-2:使用Redis做集中式缓存 邮件发送 chapter4-5-1:实现邮件发送:简单邮件、附件邮件、嵌入资源的邮件、模板邮件 消息服务 chapter5-1-1:[JMS(未完成)] chapter5-2-1:Spring Boot中使用RabbitMQ 其他功能 chapter6-1-1:使用Spring StateMachine框架实现状态机 Spring Boot Actuator监控端点小结 在传统Spring应用中使用spring-boot-actuator模块提供监控端点 Spring Boot应用的后台运行配置 Spring Boot自定义Banner Dubbo进行服务治理 chapter9-2-1:Spring Boot中使用Dubbo进行服务治理 chapter9-2-2:Spring Boot与Dubbo中管理服务依赖
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值