Java阶段二Day15

news2024/11/17 1:45:17

Java阶段二Day15

文章目录

  • Java阶段二Day15
    • 复习前日知识点
      • 对象数据类型注入
      • 数组类型注入
      • 集合类型的注入
      • p命名空间
      • 引入外部属性文件
    • 基于XML管理bean
      • bean的作用域
      • bean的生命周期
      • 代码演示生命周期
      • 后置处理器处理展示
      • 基于XML的自动装配
    • 基于注解管理bean
      • 开启组件扫描
      • 使用注解定义Bean
      • 属性值注入
        • `@Autowired`注入
        • `@Resource`注入
      • Spring全注解开发
    • 面试题
      • 描述一下bean的生命周期

复习前日知识点

对象数据类型注入

  • 引用外部bean,利用ref属性完成

    <bean> 
    	<property name = "xxx" ref = "外部bean的id"/>
    </bean>
    
  • 使用内部bean

    <bean> 
        <property name = "xxx">
        	<bean></bean>
        </property>
    </bean>
    

数组类型注入

使用<array>标签实现

  • 数组中存放普通变量

    <property name = "xxx">
        <array>
            <value>yyy</value>
            <value>zzz</value>
        </array>
    </property>
    
  • 数组中存放对象

    <property name = "xxx">
        <array>
            <ref bean = "外部bean的id"/>
            <ref bean = "外部bean的id"/>
        </array>
    </property>
    

集合类型的注入

  • List集合:使用<list>标签实现

    <property name = "xxx">
        <list>
            <value>zzz</value>
            <ref bean = "外部bean的id"/>
        </list>
    </property>
    
  • Map集合:使用<map>标签实现

    <property name = "xxx">
        <map>
            <entry>
                <key><value>key1</value></key>
                <value>yyy</value>
            </entry>
            <entry>
                <key><value>key2</value></key>
                <ref bean = "外部bean的id"/>
            </entry>
            <entry key="" value=""/>
        </map>
    </property>
    
  • 引用集合类型bean

    1. 定义util的名称空间

      xmlns:util="http://www.springframework.org/schema/util"
      
    2. 定义相关的util标签

      <util:list id="aaa">
          <value>yyy</value>
          <value>zzz</value>
      </util:list>
      
      <util:map id="bbb">
          <entry>
              <key><value>key1</value></key>
              <value>yyy</value>
          </entry>
          <entry>
              <key><value>key2</value></key>
              <ref bean = "外部bean的id"/>
          </entry>
          <entry key="" value=""/>
      </util:map>
      
    3. 使用ref属性引用

      <property name = "xxx" ref = "aaa"></property>
      <property name = "xxx" ref = "bbb"></property>
      

p命名空间

  1. 定义p的名称空间

    xmlns:p="http://www.springframework.org/schema/p"
    
  2. 使用p的语法注入

    <bean id = "xxx" class = "xxx" p:naem = "zzz" p:courseList-ref = "外部id"></bean>
    

引入外部属性文件

  1. 定义context的名称空间

    xmlns:context="http://www.springframework.org/schema/context"
    
  2. 设置外部文件xxx.properties的路径

    <!-- 引入外部属性文件 -->
    <context:property-placeholder location="classpath:xxx.properties"></context:property-placeholder>
    
  3. 使用S{变量名} 获取数据并注入

    <property name="xxx" value="${外部文件中的变量名}"></property>
    

基于XML管理bean

bean的作用域

  • 说明

    bean的作用域,是指在交给spring创建bean对象时,可以指定是单实例还是多实例,通过bean标签中的scope属性来指定,默认是单实例。

  • 单实例和多实例

    • 单实例

      单实例(Singleton)是指某个类只能创建唯一的一个实例对象,并且该类提供一个全局的访问点(静态方法)来让外界获取这个实例,常常用在那些只需要一个实例来处理所有任务的场景下,例如配置类或数据库连接池等。

    • 多实例

      多实例(Multiple Instance)则是指可以在同一个类的定义下,创建多个实例对象。每个对象都是相互独立的,有自己的状态和行为;常常用于需要同时处理多个任务的场景。

在Spring中可以通过配置bean标签的scope属性来之地那个bean的作用域范围,具体如下

取值含义创建对象时机
singleton(默认在IoC容器中,这个bean的对象为单实例IoC容器初始化时
prototype这个bean在IoC容器中有多个实例获取bean,即getBEan()时

bean的生命周期

实例化
注入属性
初始化
bean对象创建完成
销毁
  1. 实例化阶段(bean对象创建)

    在这个阶段中,容器会创建一个Bean的实例,并为其分配空间。这个过程可以通过构造方法完成。

  2. 属性赋值阶段

    在实例化完Bean之后,容器会把Bean中的属性值注入到Bean中,这个过程可以通过set方法完成。

  3. 初始化阶段(bean对象初始化)

    在属性注入完成后,容器会对Bean进行一些初始化操作;

    • 初始化之前:bean的后置处理器可以接收到bean,此处可以对bean做相关操作。
    • 初始化之后:bean的后置处理器可以接收到bean,此处可以对bean做相关操作。
  4. 使用阶段

    初始化完成后,Bean就可以被容器使用了

  5. 销毁阶段

    容器在关闭时会对所有的Bean进行销毁操作,释放资源。

代码演示生命周期

User.java

 package com.liner.spring.life;
/**
 1. 让spring创建bean对象,并继续属性注入
 2. 演示生命周期
 2.1 实例化:构造方法打印
 2.2 属性赋值:set方法打印
 2.3 初始化:定义初始化方法
 2.4 使用阶段:getBean() 之后打印测试
 2.5 销毁:手动关闭loC容器后,打印测试
 */
public class User {
    private String username;

    public User(){
        System.out.println("1-bean对象实例化,调用无参构造方法");
    }

    //初始化方法
    public void initMethod(){
        System.out.println("3-bean对象初始化,调用指定的初始化方法");
    }

    //销毁方法
    public void destoryMethod(){
        System.out.println("5-销毁bean对象,调用指定的销毁方法");
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                '}';
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        System.out.println("2-通过set方法给bean对象属性赋值");
        this.username = username;
    }
}

UserTest.java

package com.liner.spring.life;

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserTest {
    @Test
    public void test(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean-life.xml");
        User user = context.getBean("user", User.class);
        System.out.println("使用阶段----4-使用bean阶段");
        System.out.println("user = " + user);
        //销毁方法
        context.close();
    }
}

bean-life.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<!--    init-method  初始化方法  destroy-method 销毁方法 -->
    <bean id="user" class="com.liner.spring.life.User" init-method="initMethod" destroy-method="destoryMethod">
        <property name="username" value="张三"/>
    </bean>
</beans>

演示结果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XDtlr40a-1683426977559)(../../../AppData/Roaming/Typora/typora-user-images/image-20230506220934219.png)]

后置处理器处理展示

实现BeanPostProcessor接口

MyBeanPost.java

package com.liner.spring.life;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class MyBeanPost implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("3之前,初始化之前执行");
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("3之后,初始化之后执行");
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}

bean-life.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--    init-method  初始化方法  destroy-method 销毁方法 -->
    <bean id="user" class="com.liner.spring.life.User" init-method="initMethod" destroy-method="destoryMethod">
        <property name="username" value="张三"/>
    </bean>

    <!--    将后置处理器操作交给 spring-->
    <bean id="myBeanPost" class="com.liner.spring.life.MyBeanPost"/>

</beans>

演示结果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gX00ImMK-1683426977561)(../../../AppData/Roaming/Typora/typora-user-images/image-20230507085459862.png)]

基于XML的自动装配

自动装配:根据指定的策略,在IoC容器中匹配某一个bean,自动为指定的bean中的所依赖的类类型或者接口类型属性赋值

使用bean标签autowire属性设置自动装配效果

  • byType:根据类型匹配IoC容器中的某个兼容类型的bean,为属性自动赋值

    1. 如果在IoC中,没有任何一个兼容类型的bean能够为属性赋值,则该属性不装配,默认值为null
    2. 如果在IoC中,有多个兼容类型的bean能够为属性赋值,则抛出异常 NoUniqueBeanDefinitionException
  • byName

  • 将自动装配的属性名,作为bean的id在IoC容器中匹配相对应的bean进行赋值

基于注解管理bean

​ 从Java5开始,Java增加了对注解(Annotation)的支持,它是代码中的一种特殊标记,可以在编译、类加载和运行时被读取,执行相应的处理。开发人员可以通过注解在不改变原有代码和逻辑的情况下,在源代码中嵌入补充信息。

​ Spring从2.5版本开始提供了对注解技术的全面支持,我们可以使用注解来实现自动装配,简化Spring的xml配置

Spring通过注解实现自动装配:

  1. 引入依赖
  2. 开启组件扫描
  3. 使用注解定义Bean
  4. 依赖注入

开启组件扫描

​ Spring默认不使用注解装配Bean,因此需要在Spring的xml配置中,通过context:component-scan元素开启Spring Beans的自动扫描功能。开启此功能后,Spring会自动从扫描指定的包(base-package属性设置)及其子包下的所有类,如果类上使用了@Component注解,就将该类装配到容器中。

<?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:context="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">

    <!--    开启组件扫描  扫描路径当前路径包和其子包-->
    <context:component-scan base-package="com.liner.spring"/>
    
</beans>

使用注解定义Bean

Spring提供了以下多个注解,这些注解可以直接标注在java类上,将它们定义成Spring Bean。

注解说明
@Component该注解用于描述Spring中的Bean,它是一个泛化的概念,仅仅标识容器中的一个组件(Bean),并且可以作用在任何层次,例如Service层、Dao层等,使用时只需将该注解标注在相应的类上即可。
@Respository该注解用于**数据访问层(Dao层)**的类标识为Spring中的Bean,功能与@Component相同。
@Service该注解通常作用在业务层(Service层),用于将业务层的类标识为Spring中的Bean,其功能与@Component相同。
@Controller该注解通常作用在控制层(如SpringMVC的Controller),用于将控制层的类标识为Spring中的Bean,其功能与@Component相同。

注意:以上四种注解本质上都是创建Java bean对象,而且创建出来的对象没有区别,只是为了开发方便

属性值注入

@Autowired注入

单独使用@Autowired注解,默认根据类型装配(byType)

@Autowired注解有一个required属性,默认值是true,表示在注入的时候要求被注入的Bean必须存在,如果不存在则报错。如果required属性设置为false,表示注入的Bean存在或者不存在都没关系,存在就注入,不存在也不报错。

package com.liner.spring.autowired.controller;

import com.liner.spring.autowired.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {

    //方式一:属性注入
    @Autowired
    private UserService userService;

    //方式二:set方法注入
    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    //方式三:构造方法注入
    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    //方式四:形参注入  --很少使用
    public UserController(@Autowired UserService userService) {
        this.userService = userService;
    }

    //方式五:只有一个构造函数,可无注解
    public UserController(UserService userService) {
        this.userService = userService;
    }

    public void con(){
        System.out.println("controller正在运行...");
        userService.serv();
    }

}

注意:@Autowired注解根据byType定位,所以如果一个接口有多个实现类时,会报错

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1QqcV1Cu-1683426977562)(../../../AppData/Roaming/Typora/typora-user-images/image-20230507100118993.png)]

可配合@Qualifier注解一起使用,指定具体的实现类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-18HRkuZa-1683426977562)(../../../AppData/Roaming/Typora/typora-user-images/image-20230507100338377.png)]

@Resource注入

@Resource注解也可以完成属性注入,它和@Autowired注解区别如下:

  • @Resource注解JDK扩展包中的,也就是说属于JDK的一部分。所以该解释是标准注解,更加具有通用性,而@Autowired注解Spring框架自己的
  • @Resource注解默认根据名称装配byName未指定name时,使用属性名作为name,通过name找不到的话会自动启动通过类型byType装配。而@Autowired注解默认根据类型装配byType,如果想根据名称匹配,需要配合@Qualifier注解一起使用
  • @Resource注解用在属性上setter方法上
  • @Autowired注解用在属性上setter方法上构造方法上构造方法参数上

Spring全注解开发

全注解开发就是不再使用spring配置文件了,写一个配置类来代替配置文件,使用@Configuration注解标记为配置类

SpringConfig.java

package com.liner.spring.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

//声明此类为配置类
@Configuration
//开启组件扫描
@ComponentScan("com.liner.spring")
public class SpringConfig {
}

面试题

描述一下bean的生命周期

  • 第一步实例化,spring调用构造方法对bean实例化,分配出空间资源
  • 第二步属性值的注入,调用setter方法对属性值进行注入
  • 第三步初始化,可以调用指定的初始化方法进行前置操作,比如数据校验
  • 第四步使用阶段,正常使用
  • 第五步销毁,当应用程序停止时,Bean对象会销毁释放计算机资源,同时调用指定的销毁方法
  • 后置处理器在对象初始化之前可拿到当前对象做一些操作处理,在初始化之后也可以做一些处理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/497771.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【A200】 TX1核心 JetPack4.6.2版本如何修改DTB文件测试全部SPI

大家好&#xff0c;我是虎哥&#xff0c;很长时间没有发布新内容&#xff0c;主要是这段时间集中精力&#xff0c;研究DTB设备树的修改&#xff0c;以适配不同载板&#xff0c;同时也是专门做了一个TX1&TX2核心&#xff0c;双网口&#xff0c;可以使用SPI 扩展CAN接口的载板…

java获取resources路径的方法

我们在写程序的时候&#xff0c;有时候会发现代码不能正常运行&#xff0c;出现提示异常的问题&#xff0c;这就说明我们的代码没有执行完&#xff0c;也就是没有 resource&#xff0c;其实遇到这种情况&#xff0c;我们只需要把代码重新执行一遍即可。 在 java中是可以实现 re…

【计算机组成原理笔记】计算机的基本组成

计算机的基本组成 文章目录 计算机的基本组成冯诺伊曼计算机的特点硬件框图以运算器为核心的计算机现代计算机系统复杂性管理的方法 计算机的工作步骤存储器运算器控制器I/0 脚注 冯诺伊曼计算机的特点 五大部件组成 运算器存储器控制器输入设备输出设备 指令和地址以同等地位…

基于CUDA的GPU计算PI值

访问【WRITE-BUG数字空间】_[内附完整源码和文档] 基于CUDA的GPU计算PI值。本项目使用CUDA编程模型并行计算PI值&#xff0c;研究GPU与CPU效率的比较&#xff0c;分析不同GPU线程分块对性能的影响。 异构计算试验报告 —实验1&#xff1a;基于CUDA的GPU计算PI值 第一部分&…

原型模式--深拷贝和浅拷贝

定义 Specify the kind of objects to create using a prototypical instance, and create new objects by copying this prototype. &#xff08;使用原型实例指定将要创建的对象类型&#xff0c;通过复制这个实例创建新的对象。&#xff09; 从定义中我们我们可以发现&#x…

2023年4月Web3行业月度发展报告区块链篇 | 陀螺科技会员专享

4月&#xff0c;以太坊上海升级与香港Web3动向成最大热点&#xff0c;上海升级的完成是转POS的重要里程碑&#xff0c;从市场而言&#xff0c;由于升级解锁质押ETH是否引发抛压备受关注&#xff0c;仅以交易表现来看&#xff0c;并未出现大范围的抛压与离场。另一方面&#xff…

算力提升+AIGC,是驱动元宇宙发展的核心引擎|数据猿直播干货分享

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 “元宇宙”是美国科幻小说家尼奥斯蒂文森1992年在《雪崩》中提出的概念&#xff0c;书中设定现实世界中的人在网络世界中都有一个分身&#xff0c;这个由分身组成的世界就是“元宇宙”。如今&#xff0c;随着虚拟现实技术的…

60+开箱即用的工具函数库xijs更新指南(v1.2.5)

xijs 是一款开箱即用的 js 业务工具库, 聚集于解决业务中遇到的常用函数逻辑问题, 帮助开发者更高效的开展业务开发. 接下来就和大家一起分享一下v1.2.5 版本的更新内容以及后续的更新方向. 贡献者列表: 1. 数据深拷贝cloneDeep 该模块主要由 20savage 贡献, 支持 symbol, map,…

BM58-字符串的排列

题目 输入一个长度为 n 字符串&#xff0c;打印出该字符串中字符的所有排列&#xff0c;你可以以任意顺序返回这个字符串数组。 例如输入字符串ABC,则输出由字符A,B,C所能排列出来的所有字符串ABC,ACB,BAC,BCA,CBA和CAB。 数据范围&#xff1a;n < 10。 要求&#xff1a;空…

[架构之路-191]-《软考-系统分析师》-8-软件工程 - 解答什么是面向功能的结构化程序设计:算法+数据结构 = 程序

目录 1. 什么是结构化程序设计 2. 结构化程序设计的局限性 3.程序设计的三种基本结构 (1) 顺序结构 (2) 选择结构 (3) 循环结构 1. 什么是结构化程序设计 功能 》 Function 》 函数 》 算法 数据流Data Flow 》 数据结构Data Strucuture 程序 算法 数据结构 》 数…

36. Kubernetes 网络原理——CNI 网络插件

本章讲解知识点 Flannel 原理概述直接路由的原理和部署示例Calico 插件原理概述1. Flannel 原理概述 Flannel 是一个用于容器网络的开源解决方案,它使用了虚拟网络接口技术(如 VXLAN)和 etcd 存储来提供网络服务。它的原理概述如下: Flannel 协助 Kubernetes,给每一个 No…

界面交互篇:答题页的答题逻辑交互开发

微信小程序云开发实战-答题积分赛小程序 界面交互篇:答题页的答题逻辑交互开发 前面的那一篇文章,我们已经完成了使用云开发的聚合能力实现从题库中随机抽取题目功能。 在页面加载时,实现从题库中随机抽取题目功能。那么,拿到数据后要干什么?如何做? 动态数据绑定 实…

c++练习题

1、默认参数练习 创建默认参数函数 void stars(int cols ,int rows ) 该函数默认缺省值cols是10 rows是1。该函数完成功能是根据行和列数显示一个由星号组成的矩形。在main函数仲按照默认值调用该函数。按照cols是5调用该函数。按照列数和行数是7&#xff0c;3 调用该函数 #…

【MMdetection训练及使用脚本系列】MMdetection训练1——如何保存最优的checkpoint文件

MMdetection如何保存最优的checkpoint文件 以目标检测为例&#xff0c;进入到 configs/_base_/datasets/coco_detection.py将evaluation dict(interval1, metricbbox)改为evaluation dict(interval1, metricbbox, save_bestauto)即可。 但是不建议这样做&#xff0c;防止以…

软件设计师笔记--数据结构

文章目录 前言学习资料数据结构大 O 表示法时间复杂度线性结构和线性表线性表的顺序存储线性表的链式存储栈的顺序存储栈的链式存储队列的顺序存储与循环队列 串KMP 数组矩阵树二叉树二叉树的顺序存储结构二叉树的链式存储结构二叉树的遍历平衡二叉树二叉排序树最优二叉树(哈夫…

C/C++每日一练(20230507) 数列第n项值I/II、简化路径

目录 1. 求数列的第n项的值 ※ 2. 求数列的第n项的值 II ※ 3. 简化路径 &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 求数列的第n项的值 已知数列…

摘要:PostgreSQL开发技术基础:过程与函数

原文地址 6.0 Language SQL与PL/pgSQL PL / PgSQL是基于SQL的特定于PostgreSQL的过程语言 。它有循环&#xff0c;variables&#xff0c;错误/exception处理等等。并不是所有的SQL都是有效的PL / PgSQL&#xff0c;正如你发现的那样&#xff0c;例如&#xff0c;你不能在没有…

Nature:时松海课题组揭示调控大脑新皮层神经元空间精细结构排布和环路组装的新机制

2022年12月7日&#xff0c;清华大学生命科学学院、清华-IDG/麦戈文脑科学研究院、生命科学联合中心、生物结构前沿研究中心时松海教授课题组在Nature杂志以长文的形式在线发表了题为“Patterned cPCDH expression regulates the fine organization of the neocortex”&#xff…

Python心经(2)

有关数字类型&#xff0c;字符串&#xff0c;函数 目录 有关数字类型&#xff0c;字符串&#xff0c;函数 数字 字符串 索引操作 切片操作 单个字符编码 运算符 还有一些常用的内置函数 Python输入函数 输出函数print()语法 python的函数也能给默认值 Python是个脚…

什么是事件驱动的微服务架构?

对于许多关键应用程序功能&#xff0c;包括流媒体和电子商务&#xff0c;单体架构已不再足够。随着实时事件数据和云服务使用的需求增加&#xff0c;许多现代应用程序&#xff0c;如Netflix和Lyft&#xff0c;已经转向了事件驱动的微服务方法。分离的微服务可以独立运行&#x…