前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring 全家桶之 Spring Framework 5.3(二)- Part A

Spring 全家桶之 Spring Framework 5.3(二)- Part A

作者头像
RiemannHypothesis
发布2022-08-19 15:33:22
4030
发布2022-08-19 15:33:22
举报
文章被收录于专栏:Elixir

一、Spring IoC 容器 Bean 花式注册与获取

花式一:通过Bean的类型获取Bean

配置文件beans.xml保持不变,在ContainerTest中新增方法

代码语言:javascript
复制
// 通过bean类型获取bean
@Test
public void testGetBeanByClass(){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml");

    Person stark = context.getBean(Person.class);
    System.out.println(stark);
}
image.png
image.png

配置文件beans.xml新增加一个bean标签的配置

代码语言:javascript
复制
<bean id="parker" class="com.citi.entity.Person">
    <property name="lastName" value="Parker" />
    <property name="age" value="18" />
    <property name="gender" value="male" />
    <property name="email" value="peterparker@gmail.com" />
</bean>

再次执行testGetBeanByClass(),会出现如下报错: No qualifying bean of type 'com.citi.entity.Person' available: expected single matching bean but found 2: stark,parker 这是因为配置文件中有连个bean配置,获取的时候没有指定获取哪个bean,所以会报错,修改testGetBeanByClass()

代码语言:javascript
复制
// 通过bean类型获取bean
@Test
public void testGetBeanByClass(){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml");

    Person stark = context.getBean("stark",Person.class);
    System.out.println(stark);
}

输出结果如下

image.png
image.png

花式二:通过Constructor获取Bean

Person实体类中新增有参数构造方法

代码语言:javascript
复制
public Person(String lastName, Integer age, String gender, String email) {
    System.out.println("有参构造方法被调用");
    this.lastName = lastName;
    this.age = age;
    this.gender = gender;
    this.email = email;
}

beans.xml中注册所有bean标签配置,并增加如下bean标签

代码语言:javascript
复制
<bean id="parker" class="com.citi.entity.Person">
    <constructor-arg name="lastName" value="Parker" />
    <constructor-arg name="age" value="18" />
    <constructor-arg name="gender" value="male" />
    <constructor-arg name="email" value="peterparker@gmail.com" />
</bean>

ContainerTest中获取bean

代码语言:javascript
复制
@Test
public void testGetBeanByConstructor(){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml");

    Person parker = context.getBean("parker",Person.class);
    System.out.println(parker);
}

执行testGetBeanByConstructor,控制台打印结果如下

image.png
image.png

通过Constructor获取Bean时bean.xml第二种注册方式

代码语言:javascript
复制
<bean id="parker" class="com.citi.entity.Person">
    <constructor-arg value="Parker" />
    <constructor-arg value="18" />
    <constructor-arg value="male" />
    <constructor-arg value="peterparker@gmail.com" />
</bean>

name标签可以省略,但是这个顺序一定要与构造方法中属性的顺序一致,也可以添加index属性来让value和类的属性保持一致,index从0开始

代码语言:javascript
复制
<bean id="parker" class="com.citi.entity.Person">
    <constructor-arg value="Parker" index="0"/>
    <constructor-arg value="18" index="1"/>
    <constructor-arg value="male" index="2"/>
    <constructor-arg value="peterparker@gmail.com" index="3"/>
</bean>

有参构造方法重载的情况下,可以使用type执行属性值的类型

花式三:为各种属性正确赋值

新增一个实体类Car,Book

代码语言:javascript
复制
public class Car {

   private String carName;
   private Integer price;
   private String color;
   // 此处省略getter/setter/toString方法
}
代码语言:javascript
复制
public class Book {
    private String bookName;
    private String author;
    // 此处省略getter/setter/toString方法
}

给Person实体类增加属性

代码语言:javascript
复制
public class Person {

    private String lastName;
    private Integer age;
    private String gender;
    private String email;

    // 为各种属性正确赋值
    private Car car;
    private List<Book> bookList;
    private Map<String,Object> map;
    private Properties properties;

    //无参构造方法
    public Person() {
        System.out.println("无参构造方法被调用");
    }

    public Person(String lastName, Integer age, String gender, String email) {
        System.out.println("有参构造方法被调用");
        this.lastName = lastName;
        this.age = age;
        this.gender = gender;
        this.email = email;
    }
    // 此处省略getter/setter/toString方法
}      

resources目录下新建一个assgin_value.xml的bean配置文件

代码语言:javascript
复制
<?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">
</beans>

test目录下新建一个测试类AssignValueTest

代码语言:javascript
复制
public class AssignValueTest {
}
不给属性赋值,基本数据类型就是默认值,引用数据类型是null

在assing_value.xml增加bean标签

代码语言:javascript
复制
<!--不赋值,默认为Null-->
<bean id="stark" class="com.citi.entity.Person">
</bean>

AssignValueTest测试类中增加测试代码

代码语言:javascript
复制
@Test
public void testAssignNull(){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:assign_value.xml");

    Person stark = context.getBean(Person.class);
    System.out.println(stark);
}

执行testAssignNull()测试方法,属性都为null

image.png
image.png

如果要为一个属性赋值null,以lastName为例,修改xml配置文件

代码语言:javascript
复制
<!--不赋值,默认为Null-->
<bean id="stark" class="com.citi.entity.Person">
    <property name="lastName">
       <null/>
    </property>
</bean>

修改测试类,增加判断lastName是否为null

代码语言:javascript
复制
@Test
public void testAssignNull(){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:assign_value.xml");

    Person stark = context.getBean(Person.class);
    System.out.println(stark.getLastName() == null);
    System.out.println(stark);
}

控制台输出为true,说明赋值null成功,对属性赋值null要使用标签

image.png
image.png
为应用的外部的值

在xml配置文件中增加Car实体类的配置,增加一个Person实体了的bean标签配置,给Car属性赋值

代码语言:javascript
复制
<bean id="JAGUAR" class="com.citi.entity.Car">
    <property name="carName" value="JAGUAR"></property>
    <property name="color" value="英国绿"></property>
    <property name="price" value="580000"></property>
</bean>

<!--引用外部的值-->
<bean id="stark01" class="com.citi.entity.Person">
    <property name="car" ref="JAGUAR"></property>
</bean>

增加测试方法testRefOutsideValue()

代码语言:javascript
复制
@Test
public void testRefOutsideValue(){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:assign_value.xml");

    Car car = context.getBean(Car.class);
    Person stark01 = context.getBean("stark01",Person.class);
    System.out.println(stark01.getCar() == car);
    System.out.println(stark01);
    System.out.println(car);
}

执行该方法,xml配置中使用了ref标签引用容器中存在的Car配置,所以容器中的Car和Person中的Car是同一个

image.png
image.png
引用内部的Value

增加Bean xml配置

代码语言:javascript
复制
<!--引用内部的值-->
<bean id="stark02" class="com.citi.entity.Person">
    <property name="car">
        <bean class="com.citi.entity.Car">
            <property name="carName" value="Model 3"></property>
            <property name="price" value="265652"></property>
            <property name="color" value="black"></property>
        </bean>
    </property>
</bean>

增加测试方法

代码语言:javascript
复制
@Test
public void testInsideValue(){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:assign_value.xml");

    Car car = context.getBean(Car.class);
    Person stark02 = context.getBean("stark02",Person.class);
    System.out.println(stark02.getCar() == car);
    System.out.println(stark02);
    System.out.println(car);
}

容器中的Car仍然为JAGUAR,而Person中定义了Car为Model 3,两者不是同一个,输出false,使用内部的Value,要在propert标签内再定一个Bean标签

image.png
image.png
List属性赋值

增加xml配置,定义一个Book的bean标签供bookList引用,列表引用要是用ref标签

代码语言:javascript
复制
<bean id="PythonBook" class="com.citi.entity.Book">
    <property name="bookName" value="Python21天跑路"></property>
    <property name="author" value="佚名"></property>
</bean>

<!--List属性赋值-->
<bean id="stark03" class="com.citi.entity.Person">
    <property name="bookList">
        <list>
            <bean id="book01" class="com.citi.entity.Book">
                <property name="bookName" value="Java从入门到跑路"></property>
                <property name="author" value="佚名"></property>
            </bean>
            <!--引用外部-->
            <ref bean="PythonBook"></ref>
        </list>
    </property>
</bean>

增加测试方法

代码语言:javascript
复制
@Test
public void testAssign2List(){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:assign_value.xml");

    Book pythonBook = context.getBean(Book.class);
    Person stark03 = context.getBean("stark03",Person.class);
    List<Book> bookList = stark03.getBookList();
    for (Book book : bookList) {
        System.out.println(book);
    }
    System.out.println(stark03);
    System.out.println(pythonBook);
}

执行测试,控制台输出

image.png
image.png

尝试获取Person bookList属性中的另一本书,测试方法中增加代码

代码语言:javascript
复制
Book book01 = context.getBean("book01",Book.class);
System.out.println(book01);

执行测试方法报错,说明bean标签内部的bean是无法直接通过容器获取的,只有最外层定义的bean可以被容器直接获取

image.png
image.png
Map属性赋值

增加xml配置,给map属性赋值需要使用entry标签,通过key和value标签定义map结构中的key和map,也可用过key-ref和value-ref引用外部的key和value,map中可以在通过entry再嵌套map

代码语言:javascript
复制
<!--Map属性赋值-->
<bean id="stark04" class="com.citi.entity.Person">
    <property name="map">
        <map>
            <!--key,value,一个entry代表一个简直对-->
            <entry key="name" value="Peter"></entry>
            <entry key="book" value-ref="PythonBook"></entry>
            <entry key="car">
                <bean class="com.citi.entity.Car">
                    <property name="carName" value="Model Y"></property>
                </bean>
            </entry>
            <entry key="mapKey">
                <map>
                    <entry key="key01" value="value01"></entry>
                </map>
            </entry>
        </map>
    </property>
</bean>

新增测试方法

代码语言:javascript
复制
@Test
public void testAssign2Map(){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:assign_value.xml");

    Person stark04 = context.getBean("stark04",Person.class);
    Map<String, Object> map = stark04.getMap();
    for (String key : map.keySet()) {
        System.out.println("key:" + key);
    }

    for (Object value : map.values()) {
        System.out.println("value:" + value);
    }
    System.out.println(stark04);
}

执行测试方法,控制台成功打印出map数据结构

image.png
image.png
Properties属性赋值

增加xml配置,为Properties属性赋值需要使用props标签,prop标签表示properties配置文件中的每一行key-value

代码语言:javascript
复制
<!--Properties属性赋值-->
<bean id="stark05" class="com.citi.entity.Person">
    <property name="properties">
        <props>
            <prop key="username">root</prop>
            <prop key="password">12345</prop>
        </props>
    </property>
</bean>

增加测试方法

代码语言:javascript
复制
@Test
public void testAssign2Properties(){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:assign_value.xml");

    Person stark05 = context.getBean("stark05",Person.class);

    System.out.println(stark05);
}

执行测试方法,控制台成功输出properties内容

image.png
image.png
namespace名称空间

名称空间是用来防止标签重复的,通过增加前缀(名称空间)区分名字相同的标签,如

代码语言:javascript
复制
<car>
    <name>F-TYPE</name>
    <price>580000</price>
    <owner>
        <name>Stark</name>
        <age>40</age>
    </owner>
</car>

car下面的name和owner下面的name出现了重复,此时需要通过增加前缀即命名空间来区分,将xml格式数据修改为如下形式

代码语言:javascript
复制
<car>
    <c:name>F-TYPE</c:name>
    <price>580000</price>
    <owner>
        <o:name>Stark</o:name>
        <age>40</age>
    </owner>
</car>

Spring配置文件中本身就有默认的命名空间,即表头中的

代码语言:javascript
复制
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"

它表示默认的命名空间,不需要添加前缀

使用自定义的名称空间需要导入,放在表头

代码语言:javascript
复制
xmlns:p = "http://www.springframework.org/schema/p"

使用时会有很多提示

image.png
image.png

在xml中增加使用前缀的配置

代码语言:javascript
复制
<bean id="stark06" class="com.citi.entity.Person" p:lastName="stark06">
    
</bean>

增加测试方法

代码语言:javascript
复制
@Test
public void testAssignByNamespace(){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:assign_value.xml");

    Person stark06 = context.getBean("stark06",Person.class);

    System.out.println(stark06);
}

控制台成功打印出lastName为stark06

image.png
image.png
利用util名称空间为Map属性赋值

首先导入名称空间,修改表头为

代码语言:javascript
复制
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:p = "http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util-4.3.xsd">
</beans>        

接着利用util名称空间创建一个map,id为mapSample,供id为stark07的bean标签引用

代码语言:javascript
复制
<util:map id="mapSample">
    <!--key,value,一个entry代表一个简直对-->
    <entry key="name" value="Thor"></entry>
    <entry key="book" value-ref="PythonBook"></entry>
    <entry key="car">
        <bean class="com.citi.entity.Car">
            <property name="carName" value="Model Y"></property>
        </bean>
    </entry>
</util:map>

<!--引用util名称空间为Map属性赋值-->
<bean id="stark07" class="com.citi.entity.Person">
    <property name="map" ref="mapSample">
    </property>
</bean>

增加测试方法

代码语言:javascript
复制
@Test
public void testAssignMapByUtilNamespace(){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:assign_value.xml");

    Person stark07 = context.getBean("stark07",Person.class);

    System.out.println(stark07);
}

控制台日志显示,已成功赋值

image.png
image.png
利用util名称空间为List属性赋值

xml中增加util:list配置,并增加一个bean标签引用util list标签

代码语言:javascript
复制
<util:list id="listSample">
    <bean id="book02" class="com.citi.entity.Book">
        <property name="bookName" value="Java从入门到跑路"></property>
        <property name="author" value="佚名"></property>
    </bean>
    <!--引用外部-->
    <ref bean="PythonBook"></ref>
</util:list>

<!--引用util名称空间为List属性赋值-->
<bean id="stark08" class="com.citi.entity.Person">
    <property name="bookList" ref="listSample">
    </property>
</bean>

增加测试方法

代码语言:javascript
复制
@Test
public void testAssignListByUtilNamespace(){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:assign_value.xml");

    Person stark08 = context.getBean("stark08",Person.class);

    System.out.println(stark08);
}

控制台显示list已被成功赋值

image.png
image.png
级联属性赋值

Person有Car属性,Car属性又有carName属性,从Person端来看,carName就是级联属性,即属性的属性 增加xml配置

代码语言:javascript
复制
<!--级联属性赋值-->
<bean id="stark09" class="com.citi.entity.Person">
    <property name="car" ref="JAGUAR"></property>
    <!--修改引用的Car的价格-->
    <property name="car.price" value="400000"></property>
</bean>

增加测试代码

代码语言:javascript
复制
@Test
public void testAssignCascadeProperty(){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:assign_value.xml");

    Person stark09 = context.getBean("stark09",Person.class);
    Car car = context.getBean(Car.class);

    System.out.println(stark09);
    System.out.println(car);
}

控制台日志显示价格已经被成功修改,由原来的580000变为400000,并且容器中的原来的car的价格也被修改

image.png
image.png
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-01-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、Spring IoC 容器 Bean 花式注册与获取
    • 花式一:通过Bean的类型获取Bean
      • 花式二:通过Constructor获取Bean
        • 花式三:为各种属性正确赋值
          • 不给属性赋值,基本数据类型就是默认值,引用数据类型是null
          • 为应用的外部的值
          • 引用内部的Value
          • List属性赋值
          • Map属性赋值
          • Properties属性赋值
          • namespace名称空间
          • 利用util名称空间为Map属性赋值
          • 利用util名称空间为List属性赋值
          • 级联属性赋值
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档