Spring-IOC:xml注入、构造器赋值、P/C命名空间

2021-02-20 12:20

阅读:426

标签:use   没有   contex   sys   pat   version   编写   有一个   pre   

通过容器注册Bean

容器中注册Bean

  1. 新建我们的person类,写入无参 有参 get/set方法

    public class Person {
        private String lastName;
        private String gender;
        private Integer age;
        private String email;
    /*
    	有参无参
    	get/set
    	这里我进行了省略
    */
    }
    
    
  2. 新建ioc.xml 这是我们的ioc容器配置文件,注入我们的第一个bean

简单分析

  • 这就是我们第一个注册bean的过程,方式是在这xml文件中 通过bean标签 嵌套property来进行赋值
  • 一个Bean标签可以注册一个组件(对象,类)
  • id 这个对象的唯一标识 , class 写注册的组件的全类名

运行测试

  1. 在Test测试文件夹中新建Test1

    public static void main(String[] args) {
    		ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc.xml");
            Person person01 = (Person) ioc.getBean("person01");
            System.out.println(person01);
    }
    

简单分析

  • ApplicationContext:代表ioc容器,其实就是IOC容器的接口
  • ClassPathXmlApplicationContext:ioc容器的配置文件在类路径下("你的xml文件")
    FileSystemXmlApplicationContext:在磁盘下的配置文件 ("C:/ioc.xml") 一般不用
  • 我们获取对象的信息是通过 getBean方法里面传入的值就是我们在xml中bean标签的id值

Question

给容器注册一个组件(类),该对象是什么时候创建好的呢?

我们可以在 对象的无参构造上 写一个println 打印一行字

public class Person(){
      System.out.println("对象开始创建");
}

PS:当我们创建这个对象的时候 会执行这个无参构造,然后就会println
此时我们就知道什么时候创建的对象了

于是我们可以看到 :当创建好ioc容器,并读取 configLocation(.xml文件)时,print对象开始创建...
所以对象的创建是在容器启动之后开始创建完毕的,不是getBean的时候创建的
假如你的xml中注册了2个对象,先会把这2个创建完毕,即容器创建完成后输出2遍print

如果同时getBean 2次同一个对象,那么他们是相同的吗?

相同,同一个组件在ioc容器中是单实例的,容器启动完就创建好的

PS:但有一个@Scope注解,没加之前,默认的bean是单实例的,
加入@Scope(“prototype”),变成多实例,后面有不作过多赘述

如果getBean一个不存在的组件,会怎么样?

报NoSuchBeanDefinitionException: No bean named ‘这是你getbean的名字‘ available

property怎么进行赋值的

ioc容器在创建这个组件对象的时候 (property)会利用setter方法对javaBean的属性进行赋值

JavaBean(对象)的属性名是由什么决定的?
即我们在XML文件中的 name指定对应的class文件里的属性名由谁决定的?

不是由你声明好的String lastName决定,而是由你的get/set方法决定
你set方法中setXXX,这XXX就是所决定你name对应的属性名

即使你是String useName,但假设我把setuserName改成setmyName,
那么你的property中的name 就需要写myName而不是userName

Ps: 当然如果你是用lombok插件或者idea快捷键生成的set/get方法那么就不需要考虑这个问题,
除非你自己手打的才可能会出现这个错误 =.=


通过Bean类型获取bean

在xml中注册第二个组件(类)

运行测试

public static void main(String[] args) {
       ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc.xml");
       Person bean = ioc.getBean(Person.class);
       System.out.println(bean);
}

我们从之前通过getBean然后传入我们xml中bean标签的id值

我们现在是通过getBean但是传入的是我们bean的类型(就是Class所对应的类)

此时是可以获取到person01的值

Question

如果我Xml中如果有2个注册的组件(类),都是一个类型,会怎么样?

(此时我们在xml中注册了第二个bean:person02)

那么Xml中此时有person01和person02,它们都是person类型

那么此时运行则会报错 报NoUniqueBeanDefinitionException:没有输入唯一的bean定义

所以 如果ioc容器中如果这个类型的bean有多个,那么则会失败

前两种的结合写法

public static void main(String[] args) {
       ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc.xml");
       Person bean = ioc.getBean("person01",Person.class);
       System.out.println(bean);
}

第三种写法 getBean("xml中的name",xml中class对应的类型.class)

getBean("person01",Person.class); 不需要强转


通过构造器赋值

xml中注册person03

通过构造器来进行赋值的话,从property >> constructor-arg

你有参构造有几个参数 那么你就需要有几个constructor-arg 否则报错

如果你省略了name值 那么你需要按照有参构造的属性值顺序进行注入

或者可以在value后面通过index规定顺序

Question

通过构造器创建有什么不同?

1.我们之前通过property的name >> 然后通过set方法进行赋值,通过无参构造进行创建对象
2.我们现在是通过的有参构造器进行对Bean赋值,不通过无参,也不通过set/get进行赋值
PS:你的有参构造有几个参数,你的constructor-arg 就需要写几个 否则报错


通过P/C命名空间赋值

命名空间:在xml中名称空间是用来防止标签重复的

p命名空间注入的特点是使用属性而不是子元素的形式配置Bean的属性,从而简化了配置代码。

在xml中引入命名空间

 

编写bean标签

 

注意:p:属性="值" 是在第一个bean标签括号的内部


Spring-IOC:xml注入、构造器赋值、P/C命名空间

标签:use   没有   contex   sys   pat   version   编写   有一个   pre   

原文地址:https://www.cnblogs.com/pengcode/p/12500977.html


评论


亲,登录后才可以留言!