当前位置: 首页 > news >正文

网站域名备案密码新网站 被百度收录

网站域名备案密码,新网站 被百度收录,国企公司网站制作,莱州一中网站一、Bean 的作用域Bean 的作用域指 Bean 的某种行为模式。1、单例作用域(singleton,默认)在整个 Spring IoC 容器内,同名 bean 只有一个。无论用什么方式获取同名 Bean,都是一样的,并且某一地方修改了 Bean,其它地方使…

一、Bean 的作用域

        Bean 的作用域指 Bean 的某种行为模式

1、单例作用域(singleton,默认)

        在整个 Spring IoC 容器内,同名 bean 只有一个。无论用什么方式获取同名 Bean,都是一样的,并且某一地方修改了 Bean,其它地方使用的也是修改后的值。

        存储 Bean 时,若未指定作用域默认为单例作用域

// 类注解,存储 Bean
@Configuration
public class BeanConfig {
}
@RestController
@RequestMapping("/scope")
public class ScopeController {@Autowiredprivate ApplicationContext context;// 默认情况,单例作用域@Autowiredprivate BeanConfig beanConfig;// 测试默认作用域@RequestMapping("test")public String test() {return "context bean: " + context.getBean(BeanConfig.class) + "<br/>" +"config bean: " + beanConfig;}
}

        也可以指定单例作用域

public class Dog {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}
// 未指定作用域,默认单例作用域
@Configuration
public class BeanConfig {// 指定作用域为 singleton@Bean
//    @Scope("singleton")@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)public Dog singleton() {return new Dog();}
}
    // singleton 作用域@Autowiredprivate Dog singleton;// 测试单例作用域@RequestMapping("testSingleton")public String testSingleton() {return "context bean: " + context.getBean("singleton") + "<br/>" +"config bean: " + singleton;}

 

        重启后,Spring IoC 容器销毁,bean 也销毁了。

2、原型作用域(prototype,多例)

        每次使用同名 bean,都会新建实例

    // 指定作用域为 prototype@Bean//    @Scope("prototype")@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)public Dog prototype() {return new Dog();}
    // prototype 作用域@Autowiredprivate Dog prototype;// 测试原型作用域@RequestMapping("testPrototype")public String testPrototype() {return "context bean: " + context.getBean("prototype") + "<br/>" +"config bean: " + prototype;}

        下面不变的原因:@AutiWired 

3、请求作用域(request)

        每次 HTTP 请求内的同名 bean 相同。 

    // 指定作用域为 request@Bean@RequestScopepublic Dog request() {return new Dog();}
    // request 作用域@Autowiredprivate Dog request;// 测试请求作用域@RequestMapping("testRequest")public String testRequest() {return "context bean: " + context.getBean("request") + "<br/>" +"config bean: " + request;}

       每次请求,会新建 bean。

4、会话作用域(session)

        每个 HTTP 会话中,同名 bean 相同

    // 指定作用域为 session@Bean@SessionScopepublic Dog session() {return new Dog();}
    // session 作用域@Autowiredprivate Dog session;// 测试 session 作用域@RequestMapping("testSession")public String testSession() {return "context bean: " + context.getBean("session") + "<br/>" +"config bean: " + session;}

        不同浏览器,会话不同,新建 bean。

5、全局作用域(application)

        ServletContext 内同名 bean 相同ServletContext 可以认为是一个 Tomcat 容器,一个 Tomcat 可包含多个 ApplicationContext。实际开发中几乎没用,因为 Spring Boot 项目中,一个 Tomcat 只能包含一个 ApplicationContext;并且 ApplicationContext 在业务上也是隔离的,不可能这个 ApplicationContext 的 bean 放到另一个 ApplicationContext 里面用。

    // 指定作用域为 application@Bean@ApplicationScopepublic Dog application() {return new Dog();}
    // application 作用域@Autowiredprivate Dog application;// 测试全局作用域@RequestMapping("testApplication")public String testApplication() {return "context bean: " + context.getBean("application") + "<br/>" +"config bean: " + application;}

6、WebSocket 作用域

        每个 WebSocket 内的同名 bean 相同。

二、Bean 的生命周期

1、概念

  • 实例化:给 bean 分配内存空间。
  • 属性赋值:注入属性里的 bean,如 @AutoWired。
  • 初始化:a. 执行各种通知,如 BeanNameAware 接口。b. 执行初始化:初始化的自定义扩展内容实现:(注解方式) @PostConstruct;(xml 方式) init-method;(实现接口方式) BeanPostProcessor。
  • 使用
  • 销毁:销毁的自定义扩展内容实现:(注解方式) @PreDestroy;(xml 方式) destroy-method;(实现接口方式) DisposableBean。

        执行顺序图示:

2、代码演示

// 将 BeanLifeComponent 注册为 Spring Bean
@Component
public class BeanLifeComponent implements BeanNameAware {private BeanConfig beanConfig;// 1. 实例化public BeanLifeComponent() {System.out.println("执行构造函数...");}// 2. 属性赋值@Autowiredpublic void setBeanConfig(BeanConfig beanConfig) {this.beanConfig = beanConfig;System.out.println("执行 setter 方法...");}// 3. 初始化 a. 执行各种通知@Overridepublic void setBeanName(String s) {System.out.println("执行 BeanNameAware 接口的 setBeanName 方法,beanName = " + s);}// 4. 初始化 b. 执行自定义初始化方法(注解方式)@PostConstructpublic void init() {System.out.println("执行自定义初始化方法...");}// 5. 使用 beanpublic void use() {System.out.println("执行 user 方法...");}// 6. 自定义销毁方法(注解方式)@PreDestroypublic void destroy() {System.out.println("执行自定义销毁方法...");}
}

        在测试中使用,能演示销毁:

    @Testvoid contextLoads() {BeanLifeComponent bean = (BeanLifeComponent) context.getBean("beanLifeComponent");bean.use();}

3、源码阅读

        查找 AbstractAutowireCapableBeanFactory 类的 doCreateBean 方法。

(1)实例化

        doCreateBean:

        createBeanInstance:

(2)属性赋值

        doCreateBean:

        populateBean(填充 bean):

(3)初始化

        doCreateBean:

        initializeBean:

        逐个分析:

        ① invokeAwareMethouds:

        ② applyBeanPostProcessorsAfterInitialization:

        ③ invokeInitMethods:

(4)销毁

        doCreateBean:把 bean 的销毁方法注册到 Spring。        

三、Spring Boot 自动配置

        Spring 自动装配指的是 DI(依赖注入)。而 Spring 自动配置指的是,Spring 项目启动后,第三方 jar 包里的一些类、bean 对象自动存入Srping 容器,无需使用 jar 包者手动声明存入。

1、Spring 管理第三方配置类(问题重现)

        配置类:指的是第三方包希望让 Spring 管理的类,而不是所有类。

        模拟第三方 jar 包:

        Config1:2、3 类似

package com.edu.spring.config;import org.springframework.context.annotation.Configuration;@Configuration
public class Config1 {
}

        由于启动类在我们的项目中,所以扫描不到第三方的类,Spring 也就无法管理它的 bean:

    // 测试获取第三方 bean@Testvoid testConfig() {Config1 config1 = context.getBean(Config1.class);System.out.println(config1);}

(1)方法1(@Component)

        手动声明需要扫描的类所在路径:

        但这种方式不好。一是麻烦,需要一个个 jar 包声明路径。二是有时不希望让 jar 包中的所有类的 bean 让 Spring 管理(jar 包使用者可能不会用到所有功能,所以有些类所需的依赖,pom 文件中根本没有引入,让 Spring 管理反而有问题。比如我们模拟的第三方,希望 Config1、Config2 被管理,不希望 Config3),@Component 就无法做到这一点。

(2)方法2(@Import)

        将希望被 Spring 管理的类一个个列到 @Import 中:(可以做到让 jar 包部分类被管理)

        但这种方式仍然很麻烦。并且使用者不清楚哪些类希望被管理,只有 jar 包开发者最清楚。

(3)方法3(第三方提供注解,Spring Boot 采用)

        这种注解常以 @Enable 开头。第三方提供的注解,里面列出了需要被管理的类,使用者只需加上该注解即可,类似于一些中间件,会提供 @Enablexxx 注解开启第三方服务。

        实现 ImportSelector 接口,重写方法指定需要被管理的类:

public class MyImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{"com.edu.spring.config.Config1","com.edu.spring.config.Config2"};}
}

       @Enablexxx 注解定义:

        使用者加入注解,即可让第三方的 bean 让 Spring 管理:

        但这还不够好,因为每加入一个第三方中间件,都要手动加注解,不够方便

(4)方法4(约定配置类文件路径,Spring Boot 采用)

        Spring Boot 3.0.2 约定的自动配置类集合路径:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports,创建该路径:

        列出需要被自动配置的类:

        第三方包举例:pom 文件引入 mybatis 依赖,Spring Boot 会自动扫描 MyBatis 约定自动配置类文件的内容:

2、源码阅读

        启动类上的 @SpringBootApplication 注解:

        深入 @EnableAutoConfiguration:

(1)@Import({AutoConfigurationImportSelector.class})

        导入了 AutoConfigurationImportSelector.class,它实现了 ImportSelector 接口的 selectImports 方法:

        深入阅读 getAutoConfigurationEntry():debug,观察结果。

        深入阅读 getCandidateConfigurations(annotationMetadata, attributes):文件 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

        查看自动配置类文件:我的是 Spring Boot 3.0.2 版本,这里面存放的是原生的+集成的第三方的。

        这些配置类需要排除掉用户未使用的,比如 Rabbit,我们在 POM 中没有引入该依赖,所有 Rabbit 源码中导入不了相关类,导致很多报红错误:

        查看一个我们之前了解的 JDBC 事务源码:

        源码使用的 @Conditional 有条件地将 bean 交给 Spring 管理:(未达到条件的自动配置类、bean 就会被排除掉)因为我们的 pom 文件没有引入 JDBC 事务的依赖,所以找不到指定类,也就不会自动配置 DataSourceTransaction.... 类。 这也就是排除的原理。

        一些常见的 @Conditional:

(2)@AutoConfigurationPackage

        深入阅读 @AutoConfigurationPackage:                

        AutoConfigurationPackages.Registrar.class:

        如 MyBatis 实现了 ImportBeanDefinitionRegistrar 接口的 registerBeanDefinitions 方法,就可以扫描我们的项目中被 @Mapper 声明的 bean:

3、总结

        Spring Boot 自动配置原理流程:

http://www.dtcms.com/a/439276.html

相关文章:

  • 做网站开发没有人带贵阳市住房城乡建设局八大员网站
  • Vue3+TypeScript开发:从ProTable封装到Echarts联动
  • (二分、思维)洛谷 P4090 USACO17DEC Greedy Gift Takers P 题解
  • 业务层的抽取和业务层方法的实现详解
  • 【开题答辩全过程】以 “人和小区”便民快递平台为例,包含答辩的问题和答案
  • 找网络公司建网站每年收维护费手机网站会员中心模板
  • 网站建设公司谁管网络营销的发展趋势和前景
  • 网站建设公司包括哪些溧阳建设集团网站
  • wordpress访客统计插件网络优化怎么自己做网站
  • 小迪web自动笔记50
  • 网站模板交易seo 优化公司
  • 江西那家做网站公司好德州市住房和城乡建设局网站
  • 如何制作网站首页二维码生成短链接
  • GoFrame框架学习笔记
  • 东莞 网站建设淄博网站建设公司哪家好
  • 未备案运行网站2022年最新国际军事新闻
  • 门户网站集群建设域名注册服务商
  • MSF后渗透(提权)
  • 优秀的摄影作品网站企业管理课程视频
  • SNP亮相2025德莱维数字技术行业峰会
  • 中文人名生成器中文姓名姓氏名字称呼日本人名翻译人名英文人名可用于中文分词人名实体识别
  • 【Svelte】加载数据实现响应式的正确方式
  • 出售自己的网站Add-ons wordpress
  • 网络安全相关的专业术语
  • 帝国cms影视网站模板宁波网站制作哪家强
  • (一)算法
  • 23ICPC济南站补题
  • 商务网站建设ppt模板培训网站排名
  • 南阳市宛城区建设局网站设计本质
  • nacos使用指南