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

Java Spring原理 --- Bean的作用域,Bean的生命周期,Spring自动配置

文章目录

  • Spring原理
    • Bean的作用域
      • 验证是单例的
      • 多例的作用域
      • request的作用域
      • session的作用域
      • application的作用域
    • Bean的生命周期
      • 代码的使用
      • 源码阅读
    • SpringBoot自动配置

Spring原理

Bean的作用域

  1. 概念:从Context中获取对象,得到的都是同一个,这种行为模式,就称为bean的作用域
    多次获取,拿到的Bean的对象都是同一个
    在这里插入图片描述
  2. 在Spring中支持6种作用域,后4种在Spring MVC环境才生效
    (1) singleton:单例作用域
    每个Spring IoC容器内同名称的bean只有一个实例(单例)(默认)
    (2) prototype:原型作用域(多例作用域)
    每次使用该bean时会创建新的实例(非单例)
    (3) request:请求作用域
    每个HTTP 请求生命周期内, 创建新的实例(web环境中, 了解)
    (4) session:会话作用域
    每个HTTP Session生命周期内, 创建新的实例(web环境中, 了解)
    (5) Application: 全局作用域
    每个ServletContext生命周期内, 创建新的实例(web环境中, 了解)
    (6) websocket:HTTP WebSocket 作用域
    每个WebSocket生命周期内, 创建新的实例(web环境中,了解)

验证是单例的

  1. 从context中获取对象
  2. 属性注入获取对象
@Configuration
public class BeanConfig {@Beanpublic User user1(){return new User(1,"zhangsan");}// 声明作用的范围(声明了一个单例的作用域)// 声明了一个单例的对象@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)// @Scope("singleton")@Beanpublic User singleUser(){return new User();}
}// 有多个@Autowired的时候,指定名称使用哪个@Resource(name = "singleUser")private User singleUser;@RequestMapping("scope")
@RestController
public class BeanScopeController {@Autowiredprivate ConfigurableApplicationContext context;// 有多个@Autowired的时候,指定名称使用哪个@Resource(name = "singleUser")private User singleUser;@RequestMapping("/single")public String single(){// 1. 从context中获取对象String user = (String) context.getBean("singleUser");// 2. 属性注入获取对象return "从context中获取的对象 " + System.identityHashCode(user)+ "属性注入获取的对象" + System.identityHashCode(singleUser);}
}
  1. 结果展示:可以看出他们获取的是同一个对象
    在这里插入图片描述

多例的作用域

  1. 多例模式(原型模式)
    属性注入在程序启动的时候会创建一个对象,之后再重新启动,才会改变

context获取的对象,每次重新启动都会重新获取对象,因此每次对象都会发生变化
在这里插入图片描述

 //对象@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)@Beanpublic User prototypeUser(){return new User();}// 注解
@Resource(name = "prototypeUser")private User prototypeUser;@RequestMapping("/phototype")public String phototype(){// 1. 从context中获取对象User user = (User) context.getBean("prototypeUser");// 2. 属性注入获取对象return "从context中获取的对象 " + System.identityHashCode(user)+ "属性注入获取的对象" + System.identityHashCode(prototypeUser);}
  1. 展示效果:每次刷新,拿到的不是同一个对象,每次请求都会生成一个新的对象
    在这里插入图片描述

  2. 出现的问题:没有验证成功的原因是我们写的是同一个User对象,@Data中的hashcode()会根据id判断他们是否是同一个对象,**这里的new User()都是同一个对象,那么这里就判断了他们是同一个对象,Spring进行了优化,**因此每次request刷新都不变,理论上每次刷新,都会创建一个新的对象,每次都会变化
    这里就要使用jdk,自带的toString()方法,jdk有hashcode()方法,用自带的toString()方法,它每次new都会生成不同的对象,因此可以看出request,每次都是变化的了
    所以这里不同@Data,而用@Getter和@Setter
    在这里插入图片描述

在这里插入图片描述
对上面问题的再一次解释:
Spring使用了代理模式,所以代理的User,每次都是同一个

在这里插入图片描述
在这里插入图片描述
Spring中才有代理模式:
在这里插入图片描述

request的作用域

  1. @RequestScope等同于@Scope,这两者含义是一样的
    在这里插入图片描述
  2. 虽然是同一个对象,但是每次请求都会重新创建对象
    在这里插入图片描述
// request的作用域
@RequestScope@Beanpublic User requestUser(){return new User();}// 注解的方式
@Resource(name = "requestUser")private User requestUser;@RequestMapping("/request")public String request(){// 1. 从context中获取对象User user = (User) context.getBean("requestUser");// 2. 属性注入获取对象return "从context中获取的对象 " + System.identityHashCode(user)+ "属性注入获取的对象" + System.identityHashCode(requestUser);}

session的作用域

  1. 在不同的浏览器下,是不同的会话,自然会出现不同的地址
@SessionScope@Beanpublic User sessionUser(){return new User();}
@Resource(name = "sessionUser")private User sessionUser;@RequestMapping("/session")public String session(){// 1. 从context中获取对象User user = (User) context.getBean("sessionUser");// 2. 属性注入获取对象return "从context中获取的对象 " + System.identityHashCode(user)+ "属性注入获取的对象" + System.identityHashCode(sessionUser);}
  1. 效果展示:
    如果是同一个浏览器,并且没有清除cookie,那么session不会发生变化
    在这里插入图片描述
    如果是不同的浏览器,就是不同的cookie,session自然会发生变化
    在这里插入图片描述

application的作用域

  1. application的作用域:在整个应用中都是同一个的,和我们的单例一样,在同一个应用中都是同一个

  2. 两者的区别:一个web容器中(一个tomcat中),可以部署多个服务(多个ApplicationContext),而一个Web容器中有多个ServletContext - 每个Web应用都有自己独立的ServletContext实例

一个tomcat可以启动多个web服务
在这里插入图片描述

@ApplicationScope@Bean("applicationUser")// 指定名字public User applicationUser(){return new User();}// 注解注入
@Resource(name = "applicationUser")private User applicationUser;@RequestMapping("/application")public String application(){// 1. 从context中获取对象User user = (User) context.getBean("applicationUser");// 2. 属性注入获取对象return "从context中获取的对象 " + user+ "属性注入获取的对象" + applicationUser;}
  1. 在不同的浏览器中,进行展示,都是同一个
    在这里插入图片描述

Bean的生命周期

代码的使用

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

Bean 的生命周期分为以下5个部分:
2. 实例化(为Bean分配内存空间)
3. 属性赋值(Bean注入和装配, 比如 @AutoWired )
4. 初始化
a. 执行各种通知, 如 BeanNameAware , BeanFactoryAware ,
ApplicationContextAware 的接口方法.
b. 执行初始化方法
▪ xml定义 init-method
▪ 使用注解的方式 @PostConstruct
▪ 执行初始化后置方法( BeanPostProcessor )
5. 使用Bean
6. 销毁Bean
a. 销毁容器的各种方法, 如 @PreDestroy , DisposableBean 接口方法, destroy-
method

举个例子:
在这里插入图片描述
2. 写一个案例,来验证Bean的生命周期

// BeanLifeComponent
@Component
public class BeanLifeComponent {private User user;// 构造public BeanLifeComponent() {System.out.println("执行构造方法~");}// 属性注入// 指定注入的对象// 表示注入的user1对象@Qualifier("user1")@Autowiredpublic void setUser1(User user) {this.user = user;System.out.println("属性注入~");}// 初始化// 使用@PostConstruct实现初始化@PostConstruct // 这个用的比较多public void init(){System.out.println("执行初始化方法~");}// 使用public void use(){System.out.println("执行use方法~");}// 销毁// 基本上不会用@PreDestroy // pre表示 bean 销毁前执行,销毁的时候就直接清理对象了public void destroy(){System.out.println("执行destroy销毁方法~");}
}// 测试方法
public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(SpringConfigApplication.class, args);BeanLifeComponent lifeComponent = context.getBean(BeanLifeComponent.class);lifeComponent.use();// 有不手动点击结束进程的方式来执行destroy方法// ((AbstractApplicationContext)context).destroy();}

展示效果:
在这里插入图片描述
手动关闭进程:
在这里插入图片描述

源码阅读

了解生命周期的分类

  1. bean的实例化,属性注入,bean的初始化

在这里插入图片描述
2. 执行各种通知,这些通知都是在初始化方法之前执行,属性注入之后执行的
在这里插入图片描述
在这里插入图片描述

SpringBoot自动配置

  1. 这些注解的底层就是Spring自动配置的

  2. 元注解:是注解其他注解的注解

在这里插入图片描述
在这里插入图片描述
有选择地导入配置类
在这里插入图片描述

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

相关文章:

  • TCP三次握手与四次挥手通俗理解
  • 电商网站如何设计内容能源产品网站建设多少钱
  • 门户网站的发布特点网站子栏目设计
  • 赣州企业网站建设公司苏州网站定制公司哪家好
  • 网页设计与网站建设的课后习题答案外贸 企业网站 建设
  • 呼伦贝尔网站建设平台海口网站运营托管费用
  • 网站外包费用怎么做分录个人做广播网站需要注意什么
  • 教育网站设计欣赏建一个公司网站要多少钱
  • 广州快速建站公司推荐做关于植物的网站
  • 厦门网站建设哪家专业黔东南小程序开发公司
  • 网站开发公司安心加盟苏州排名搜索优化
  • 响应式网站公司怎么做网站
  • 老师问我做网站用到什么创新技术江苏网站建设空间
  • wordpress 菜单没了网站关键词排名seo
  • 立网站系网站开发用什么工具好
  • html 网站开发软件网站永久免费建站
  • 万网网站开发世界500强企业中国有哪些
  • 漳州招商局规划建设局网站饿了么网站做生鲜吗
  • 官方网站优化方法字体设计转换器
  • 丽江网站建设c3sales软件app开发培训
  • 网站建设培训相关资料进入wordpress后台
  • 汽车网站建设需要多少钱西安印象网站建设
  • 西安网站网页设计电商平台seo
  • 阜新网站开发公司大连网站建设网站建设
  • 网站建设知识文章wordpress添加友链申请
  • 没有网站怎么做cps申请永久网站空间
  • 做网站设计比较好的公司wordpress学院
  • 毕业设计网站开发任务安排做网站大概要多
  • 用国外服务器做违法网站wordpress如何缩短连接
  • 游戏网站免费入口西城网站建设浩森宇特