zoukankan      html  css  js  c++  java
  • 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标签括号的内部

  • 相关阅读:
    安卓客户端获取手机号码
    安卓自定义控件之设计自己的提示dialog
    一步步打造自己的分页控件4
    C#winform小游戏之贪吃蛇重温C#
    android观察者模式
    Android开发之Java设计模式
    Android 用Animationlist实现逐帧动画
    图片压缩
    Android使用缓存优化ListView
    Android命令行启动程序正确使用技巧解析
  • 原文地址:https://www.cnblogs.com/pengcode/p/12500977.html
Copyright © 2011-2022 走看看