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

通过容器注册Bean

1.容器中注册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

    <?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
            https://www.springframework.org/schema/beans/spring-beans.xsd">
    	
        <!-- 注册一个Person对象 Spring会自动创建这个Person对象 -->
           <!--
            一个Bean标签可以注册一个组件(也就是对象,类)
            class 写注册的组件的全类名
            id 这个对象的唯一标识
        -->
        <bean id="person01" class="com.jiang.bean.Person">
            <property name="lastName" value="张三"></property>
            <property name="age" value="18"></property>
            <property name="gender" value="男"></property>
            <property name="email" value="123456@qq.com"></property>
        </bean>
    </beans>
    

简单分析

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

2.运行测试

  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

1.在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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
	
    <bean id="person01" class="com.jiang.bean.Person">
        <property name="lastName" value="张三"></property>
        <property name="age" value="18"></property>
        <property name="gender" value="男"></property>
        <property name="email" value="123456@qq.com"></property>
    </bean>
    
    <!-- 这是为第二个test 测试如果2个同类型注册的组件通过bean类型读取会有什么效果 -->
    <bean id="person02" class="com.jiang.bean.Person">
        <property name="lastName" value="王五"></property>
    </bean>

</beans>

2.运行测试

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); 不需要强转


通过构造器赋值

1.xml中注册person03

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 这是第三个test 测试通过构造器的方式为bean赋值 -->
    <bean id="person03" class="com.jiang.bean.Person">
        <!-- 调用有参构造器进行创建对象并赋值 -->
        <!-- public Person(String lastName, String gender, Integer age, String email) -->
        <constructor-arg name="lastName" value="小明"></constructor-arg>
        <constructor-arg name="age" value="18"></constructor-arg>
        <constructor-arg name="email" value="123456@qq.com"></constructor-arg>
        <constructor-arg name="gender" value="男"></constructor-arg>
    </bean>

    <!-- 这是第三个test 测试通过构造器的方式为bean赋值 可以省略name 但必须按照顺序-->
    <bean id="person04" class="com.jiang.bean.Person">
        <!-- 调用有参构造器进行创建对象并赋值 -->
        <!-- public Person(String lastName, String gender, Integer age, String email) -->
        <constructor-arg value="小明"></constructor-arg>
        <constructor-arg value="男" index=3></constructor-arg>
        <constructor-arg value="18"></constructor-arg>
        <constructor-arg value="123456@qq.com"></constructor-arg>

    </bean>

</beans>

通过构造器来进行赋值的话,从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的属性,从而简化了配置代码。

1.在xml中引入命名空间

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       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">

</beans>

2.编写bean标签

 <bean id="person05" class="com.jiang.bean.Person"
        p:age="18" p:email="123456@qq.com" p:gender="男" p:lastName="小孙"        >

</bean>

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

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