Spring(一)-初识 + DI+scope

1、获取bean实例的三种方式


    UTF-8
    4.3.18.RELEASE
    1.16.18
    4.11

        org.springframework
        spring-beans
        ${spring.version}

        org.springframework
        spring-core
        ${spring.version}

        org.springframework
        spring-context
        ${spring.version}

        org.springframework
        spring-expression
        ${spring.version}


  • id 属性:被spring容器进行管理的实例的 唯一标识,整个容器中,只能是唯一的(不可重复);
  • class属性:指定创建当前实例对象的类型(全类名),spring底层是使用的 反射机制 ,根据指定的目标类型,创建目标实例(必须有 空参构造)
    *
  • name:指定对象的属性名
  • value: 给属性赋值
@Test
public void testSpringPrimer(){
    //1.创建spring的核心容器对象(引用上下文对象),解析spring的核心配置文件,将文件中的bean标签进行实例化(创建对象并赋值)
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

    //2. 写法一: 从容器中获取实例对象,根据核心配置文件中,配置的bean标签的id属性值
    //            不足:强制转化,容易出现转换错误
    User userOne = (User) context.getBean("userOne");

    userOne.sayHello();

    //对比以前创建对象的写法(对象必须手动new创建,并手动赋值)
    User userOld = new User();
    userOld.setNickName("kh96_old");
    userOld.sayHello();

}

通过id属性,获取实例对象后 需要强制转换,容易出现 强制转化错误

//写法二:从容器中获取实例对象,根据核心配置文件中,配置的bean标签的class属性指定的目标类型
User userTwo = context.getBean(User.class);

userTwo.sayHello();

不足:如果 存在同类型的多个实例,会 报异常

当用多个同类型的实例:

...

...

User userTwo = context.getBean(User.class);

会发生异常:

NoUniqueBeanDefinitionException: No qualifying bean of type ‘com.kgc.spring.bean.User’ available: expected single matching bean but found 2: userOne,userTwo

主要原因是由于 只用class属性去获取实例,但是有多个相同类型的实例,所以 无法确定你要获取的是哪一个

//写法三:从容器中获取实例对象,根据配置文件中,配置的bean标签的id属性值和class属性指定的目标类型
 User userTwoThree = context.getBean("userTwo", User.class);

能够 确定唯一实例,推荐使用;

配置文件中的 id必须是唯一的;

如果id不唯一:两个id一样的实例

...

...

报错:

BeanDefinitionParsingException: Configuration problem: Bean name ‘userOne’ is already used in this

提示 id 为 userOne 的实例已经存在;

初始化spring的容器对象时,会 将核心配置文件中所有的bean实例化,不是使用哪个,创建哪个;

2、DI

IOC(控制反转是一种思想),DI是IOC的一种实现方式;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {

    //用户昵称
    //普通参数
    private String nickName;

    //私家车
    //实体参数
    private Car car;

    //喜欢的书
    //数组参数
    private String[] books;

    //爱好
    //list集合参数
    private List hobbies;

    //喜欢的游戏
    //set 集合
    private Set games;

    //卡包
    //map参数
    private Map cards;

    //在校信息
    //properties参数
    private Properties info;

    //是否有女朋友 (主要是演示赋值为null,其他类型都可以)
    //空参数注入
    private Boolean wife;

}
...

            红楼梦
            水浒传
            三国演义
            西游记

            跑步
            尤克里里
            敲代码

            唱歌
            跳舞
            喝酒

            123456
            男
            化羽

...

@Test
public void testPramsDI(){
    User user01 = context.getBean("user01", User.class);
    //输入对象详情
    System.out.println(user01);
}

输出结果:

User(
     nickName=小气鬼,
     car=Car(brand=Bmw325, factory=华晨, price=300000.0),
     books=[红楼梦, 水浒传, 三国演义, 西游记],
     hobbies=[跑步, 尤克里里, 敲代码],
     games=[唱歌, 跳舞, 喝酒],
     cards={身份证=1212121212121212, 银行卡=1111111111111111},
     info={学号=1913001072, 性别=男, 姓名=化羽},
     wife=null
    )

@Test
public void testSpringDIConstructor(){
    Car carTwo = context.getBean("carTwo", Car.class);

    //输出对象详情
    System.out.println(carTwo);
}

@Test
public void testSpringDIConstructor2(){
    Car carTwo = context.getBean("carThree", Car.class);

    //输入对象详情
    System.out.println(carTwo);
}

自定义实体工厂bean ,必须 实现FactoryBean接口

普通bean 与 工厂bean 的区别:

  • 普通 bean:在 配置文件中定义 bean 类型 就是 返回类型
  • 工厂 bean:在 配置文件定义 bean 类型返回类型 不一样
@Data
@ToString
public class Car {
    /*
     品牌
     */
    private String brand;

    /*
    厂商
     */
    private String factory;

    /*
    价格
     */
    private Double price;
}
  • spring容器初始化时,创建 当前工厂bean的实例对象,但是 真实返回不是当前类的实例对象而是当前类的实例对象返回的目标实例对象(自定义);
  • 作用:可以 在程序中,实现 自定义创建实例(还可以增加业务逻辑处理),放入容器;
  • 存在的原因:spring框架 对外开放了一个入口,可以让其他的 开发人员参与到spring底层创建bean的实例过程中去给整合其他框架使用的,比如mybatis;
public class CarFactoryBean implements FactoryBean {
    @Override
    public Car getObject() throws Exception {
        System.out.println("通过CarFactoryBean的实例对象的getObject方法:返回一个自定义的car的实例");
        return new Car("Byd唐","南京",2500000.0);
    }

    @Override
    public Class getObjectType() {
        //指定给Object方法返回的目标类型
        return Class.class;
    }

    @Override
    public boolean isSingleton() {
        //是否单例
        return false;
    }
}
...

...

@Test
public void testSpringFactoryBean(){
    //从容器中获取工厂bean的实例对象
    Car car1 = context.getBean("carFactoryBean", Car.class);
    Car car2 = context.getBean("carFactoryBean", Car.class);

    //输出对象详情
    System.out.println(car 1);
    //在容器中添加的实例是  CarFactoryBean 类型,返回的是
    //Car(brand=Byd唐, factory=南京, price=2500000.0)
    System.out.println("car1 == car2 : " + ( car1 == car2));
    //false  说明工厂bean是多例的

}

3、scope 作用域

  • singleton 单例 (默认) 容器初始化之前创建;
  • prototype 多例 (手动设置) 使用到的时候才创建;

这里 区别于整个程序运行期间有且只有唯一的实例( 单例模式-懒汉和饿汉);

容器中bean的单例不是指当前类的实例在容器中, 只有唯一的实例,而是当 创建bean的实例时,此实例是 单例(容器内唯一),但是 同一个类的实例,容器中 可以创建多个每个都是单例的


@Test
public void testScopeSingleton(){

    //从容器中,获取Bus的实例对象
    Bus busThree = context.getBean("busTwo", Bus.class);
    Bus busFour = context.getBean("busTwo", Bus.class);

    System.out.println(busThree);
    System.out.println(busFour);

    System.out.println("singleton busThree == busFour:"+(busThree == busFour));
    //true
}

多例: prototype,不是spring容器中的默认作用, 需要单独指定

spring容器创建时, 不会自动创建指定作用域为多例的bean的实例,而是每次 通过getBean方法获取bean的实例, 才会创建bean的实例


@Test
public void testScopePrototype(){
    Bus busOne = context.getBean("busThree", Bus.class);
    Bus busTwo = context.getBean("busThree", Bus.class);

    //输入详情
    System.out.println(busOne);
    System.out.println(busTwo);

    System.out.println("prototype busOne == busTwo:"+(busOne == busTwo));
    //false

}

Original: https://www.cnblogs.com/xiaoqigui/p/16625420.html
Author: 化羽羽
Title: Spring(一)-初识 + DI+scope

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/621546/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • MySQL InnoDB缓存

    1. 背景 对于各种用户数据、索引数据等各种数据都是需要持久化存储到磁盘,然后以”页”为单位进行读写。 相对于直接读写缓存,磁盘IO的成本相当高昂。 对于读…

    数据库 2023年6月14日
    0152
  • 浅谈多线程中数据的绑定和赋值

    我们知道,微软的.NET控件做了大量的工作,用起来还是不错的,一般的数据绑定或者赋值比较简单。如下所示 文本赋值: txtTest.Text = “abc”…

    数据库 2023年6月11日
    068
  • MySQL实战45讲 9

    09 | 普通索引和唯一索引,应该怎么选择? 每个人都有一个唯一的身份证号,而且业务代码已经保证了不会写入两个重复的身份证号。如果市民系统需要按照身份证号查姓名,就会执行类似这样的…

    数据库 2023年6月16日
    0111
  • 小米路由器3刷x-wrt分享

    准备工作 刷机有风险,操作需谨慎,建议使用备用路由器,以免与世隔绝。原文教程较为详细,因此本文就文件分享,及操作经验,具体请观看原文。 小米路由器3官方降级固件: http://b…

    数据库 2023年6月11日
    0101
  • Linux–>网络配置

    虚拟机NAT网络关系图 在Linux中查看网络配置 ifconfig ping 测试主机之间网络连通性 测试当前服务器是否可以连接目的主机 ping 目&am…

    数据库 2023年6月14日
    090
  • 手把手教你使用 Java 在线生成 pdf 文档

    一、介绍 在实际的业务开发的时候,研发人员往往会碰到很多这样的一些场景,需要提供相关的电子凭证信息给用户,例如网银/支付宝/微信购物支付的电子发票、订单的库存打印单、各种电子签署合…

    数据库 2023年6月14日
    0115
  • Javascript基础

    作者导言: 引用偶像刘德华的一句话 “学到的就要教人,赚到的就要给人”! 以下是关联的web前端基础知识文章,通过这些文章,您既可以系统地学习和了解这些知识…

    数据库 2023年6月14日
    0107
  • 设计模式之(1)——简单工厂模式

    创建型模式:主要用于对象的创建; 结构型模式:用于处理类或者对象的组合; 行为型模式:用于描述类或对象怎样交互和分配职责; ————————————————————————————…

    数据库 2023年6月14日
    0100
  • MySQL 安全管理

    权限表 MySQL 服务器通过权限表来控制用户对数据库的访问,由 mysql_install_db 脚本初始化,MySQL 会根据这些权限表的内容为每个用户赋予相应的权限 user…

    数据库 2023年5月24日
    088
  • Mysql-5.7主从部署-yum方式

    一、环境准备 rpm -qa |grep mariadb |xargs yum remove -y setenforce 0(临时关闭),(selinux配置文件:SELINUX=…

    数据库 2023年5月24日
    066
  • Java学习-第一部分-第二阶段-项目实战:坦克大战【1】

    坦克大战【1】 笔记目录:(https://www.cnblogs.com/wenjie2000/p/16378441.html) 坦克大战游戏 为什么写这个项目✔好玩✔涉及到ja…

    数据库 2023年6月11日
    080
  • Etcd 使用场景:通过分布式锁思路实现自动选主

    分布式锁?选主? 分布式锁可以保证当有多台实例同时竞争一把锁时,只有一个人会成功,其他的都是失败。诸如共享资源修改、幂等、频控等场景都可以通过分布式锁来实现。 还有一种场景,也可以…

    数据库 2023年6月6日
    099
  • MySQL 中 bigint、int、mediumint、smallint、tinyint 有符号和无符号的取值范围

    想要了解取值范围首先需要知道的是 bit 和 Byte 的概念 bit :位 二进制数系统中,位通常简写为 “b”,也称为比特,每个二进制数字 0 或 1 …

    数据库 2023年5月24日
    089
  • 我的创作纪念日

    机缘 2018 年 08 月 07 日是我的创作一周年纪念日。大三刚过完,我还是一名 IT 小白,也并没有考研的想法,当时应该是在实习,偶尔一次上网搜索代码问题的时候看到了 CSD…

    数据库 2023年6月6日
    099
  • etcd和Zookeeper孰优孰劣对比

    背景 最近在看到Pachyderm的介绍时,看到作者拿YARN和Kubernetes做类比,拿Zookeeper和etcd做对比。YARN和Kubernetes的类比还相对比较好理…

    数据库 2023年6月11日
    099
  • 多商户商城系统功能拆解30讲-平台端营销-商家优惠券

    多商户商城系统,也称为B2B2C(BBC)平台电商模式多商家商城系统。可以快速帮助企业搭建类似拼多多/京东/天猫/淘宝的综合商城。 多商户商城系统支持商家入驻加盟,同时满足平台自营…

    数据库 2023年6月14日
    099
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球