Chapter 02 – Spring IoC Container Bean Fancy Registration and Retrieval

Fancy one: Get the Bean by its type

The configuration file beans.xml remains unchanged and methods are added to ContainerTest

// Get beans by bean type
@Test
public void testGetBeanByClass(a){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml");

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

Configuration file beans.xml adds a new bean tag configuration

<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="[email protected]" />
</bean>
Copy the code

No qualifying bean of type ‘com.citi.entity.Person’ available: expected single matching bean but found 2: TestGetBeanByClass () : = testGetBeanByClass() : = testGetBeanByClass()

// Get beans by bean type
@Test
public void testGetBeanByClass(a){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml");

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

The output is as follows

Trick 2: Get the Bean from Constructor

A parameter constructor is new to the Person entity class

public Person(String lastName, Integer age, String gender, String email) {
    System.out.println("Parameterized constructor called");
    this.lastName = lastName;
    this.age = age;
    this.gender = gender;
    this.email = email;
}
Copy the code

Register all bean tag configurations in beans.xml and add the following bean tags

<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="[email protected]" />
</bean>
Copy the code

Gets the bean in ContainerTest

@Test
public void testGetBeanByConstructor(a){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml");

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

Execute testGetBeanByConstructor and the console prints the following result

Bean.xml is the second registration method when obtaining beans from Constructor

<bean id="parker" class="com.citi.entity.Person">
    <constructor-arg value="Parker" />
    <constructor-arg value="18" />
    <constructor-arg value="male" />
    <constructor-arg value="[email protected]" />
</bean>
Copy the code

The name tag can be omitted, but the order must be consistent with the order of the attributes in the constructor, or the index attribute can be added to keep the value consistent with the class attributes, starting at 0

<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="[email protected]" index="3"/>
</bean>
Copy the code

When the parameter constructor is overloaded, you can use type to execute the type of the attribute value

Trick 3: Assign the correct values to various attributes

Add an entity class Car,Book

public class Car {

   private String carName;
   private Integer price;
   private String color;
   // Omit getter/setter/toString methods here
}
Copy the code
public class Book {
    private String bookName;
    private String author;
    // Omit getter/setter/toString methods here
}
Copy the code

Add attributes to the Person entity class

public class Person {

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

    // Assign the various attributes correctly
    private Car car;
    private List<Book> bookList;
    private Map<String,Object> map;
    private Properties properties;

    // no argument constructor
    public Person(a) {
        System.out.println("No argument constructor called");
    }

    public Person(String lastName, Integer age, String gender, String email) {
        System.out.println("Parameterized constructor called");
        this.lastName = lastName;
        this.age = age;
        this.gender = gender;
        this.email = email;
    }
    // Omit getter/setter/toString methods here
}      
Copy the code

Create a new bean configuration file for assgin_value.xml in the Resources directory


      
<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>
Copy the code

Create a test class AssignValueTest in the test directory

public class AssignValueTest {}Copy the code

Add bean tags to assing_value.xml without assigning attributes, base datatype is default, reference datatype is null

<! Default: Null-->
<bean id="stark" class="com.citi.entity.Person">
</bean>
Copy the code

Add test code to AssignValueTest test class

@Test
public void testAssignNull(){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:assign_value.xml");

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

Execute the testAssignNull() test method, both of which are null

If you want to assign null to an attribute, use lastName as an example to modify the XML configuration file

<! Person"> <property name="lastName"> < Null /> </property> </bean>Copy the code

Modify the test class to determine whether lastName is null

@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);
}
Copy the code

The console output is true, indicating that the assignment of NULL was successful. Assigning a property to NULL uses a label

Add the Car entity class configuration to the XML configuration file for the external values of the application, add a bean tag configuration for the Person entity, and assign a value to the Car attribute

<bean id="JAGUAR" class="com.citi.entity.Car">
    <property name="carName" value="JAGUAR"></property>
    <property name="color" value="British Green"></property>
    <property name="price" value="580000"></property>
</bean>

<! -- reference external values -->
<bean id="stark01" class="com.citi.entity.Person">
    <property name="car" ref="JAGUAR"></property>
</bean>
Copy the code

Added test method testRefOutsideValue()

@Test
public void testRefOutsideValue(a){
    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);
}
Copy the code

Using this method, the XML configuration uses the REF tag to refer to the Car configuration that exists in the container, so the Car in the container and the Car in Person are the same

Add Bean XML configuration by referring to the internal Value

<! -- reference internal values -->
<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>
Copy the code

Add test methods

@Test
public void testInsideValue(a){
    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);
}
Copy the code

The container Car is still JAGUAR, and the Person Car is Model 3. The two are not the same, print false, use the internal Value, and specify a Bean tag inside the propert tag

List attribute assignment adds XML configuration to define a Book bean tag for bookList reference, which uses ref tag

<bean id="PythonBook" class="com.citi.entity.Book"> <property name="bookName" value="Python21 days running "></property> <property Name ="author" value=" author" ></property> </bean> <! Class ="com.citi.entity.Person"> <property name="bookList"> < List > <bean id="book01" Class ="com.citi.entity.Book"> <property name="bookName" value="Java from start to run "></property> <property name="author" </property> </bean> <! - refer to external - > < ref bean = "PythonBook" > < / ref > < list > < / property > < / bean >Copy the code

Add test methods

@Test
public void testAssign2List(a){
    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);
}
Copy the code

Perform test, console output

Try to get another book in the Person bookList property and add code to the test method

Book book01 = context.getBean("book01",Book.class);
System.out.println(book01);
Copy the code

An error occurs when executing the test method, indicating that beans inside the bean tag cannot be retrieved directly from the container. Only beans defined in the outermost layer can be retrieved directly from the container

Map attribute assignment adds XML configuration. Assign values to Map attributes using entry tags. Define keys and maps in the Map structure using key and value tags, and reference external keys and values using key-ref and value-ref. You can nest a map through entry

<! --Map attribute assignment -->
<bean id="stark04" class="com.citi.entity.Person">
    <property name="map">
        <map>
            <! -- Key,value, an entry represents an 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>
Copy the code

New test method

@Test
public void testAssign2Map(a){
    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);
}
Copy the code

After executing the test method, the console successfully prints out the MAP data structure

Assigning the Properties attribute adds the XML configuration. Assigning the Properties attribute requires the props tag, and the prop tag represents each line of key-value in the Properties configuration file

<! Class ="com.citi.entity.Person"> <property name=" Properties "> <props> <prop key="username">root</prop> <prop key="password">12345</prop> </props> </property> </bean>Copy the code

Add test methods

@Test
public void testAssign2Properties(a){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:assign_value.xml");

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

    System.out.println(stark05);
}
Copy the code

After executing the test method, the console successfully prints the properties content

Namespaces are used to prevent tag duplication by adding prefixes (namespaces) to distinguish tags with the same name, such as

<car>
    <name>F-TYPE</name>
    <price>580000</price>
    <owner>
        <name>Stark</name>
        <age>40</age>
    </owner>
</car>
Copy the code

The name under CAR is the same as the name under owner. In this case, you need to add a prefix (namespace) to distinguish the name and change the XML data to the following format

<car>
    <c:name>F-TYPE</c:name>
    <price>580000</price>
    <owner>
        <o:name>Stark</o:name>
        <age>40</age>
    </owner>
</car>
Copy the code

The Spring configuration file itself has a default namespace, in the header

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"
Copy the code

It represents the default namespace and does not require a prefix

Use custom namespaces that need to be imported and placed in the table header

xmlns:p = "http://www.springframework.org/schema/p"
Copy the code

There are a lot of hints when you use it

Add a configuration to use prefixes in XML

<bean id="stark06" class="com.citi.entity.Person" p:lastName="stark06">
    
</bean>
Copy the code

Add test methods

@Test
public void testAssignByNamespace(a){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:assign_value.xml");

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

    System.out.println(stark06);
}
Copy the code

The console successfully printed lastName as stark06 Assign values to Map attributes using the util namespace

First import the namespace and change the table header to

<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>        
Copy the code

Next, using the util namespace, create a map with the id mapSample that will be referenced by the bean label with the ID stark07

<util:map id="mapSample"> <! - the key, the value, An entry represents an absolute pair --> <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> <! <bean id="stark07" class="com.citi.entity.Person"> <property name=" Map "ref="mapSample"> </property> </bean>Copy the code

Add test methods

@Test
public void testAssignMapByUtilNamespace(){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:assign_value.xml");

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

    System.out.println(stark07);
}
Copy the code

The console log shows that the assignment was successful

Add the util: List configuration to the List attribute assignment XML using the util namespace, and add a bean tag that references the util List tag

<util:list id="listSample">
    <bean id="book02" class="com.citi.entity.Book">
        <property name="bookName" value="Java from entry to exit"></property>
        <property name="author" value="Anonymous"></property>
    </bean>
    <! -- Reference external -->
    <ref bean="PythonBook"></ref>
</util:list>

<! Use the util namespace to assign to the List attribute -->
<bean id="stark08" class="com.citi.entity.Person">
    <property name="bookList" ref="listSample">
    </property>
</bean>
Copy the code

Add test methods

@Test
public void testAssignListByUtilNamespace(a){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:assign_value.xml");

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

    System.out.println(stark08);
}
Copy the code

The console shows that list has been successfully assigned

Cascading property assignmentPerson has a Car attribute, which in turn has a carName attribute. From the perspective of the Person side, carName is a cascading attribute, that is, the attributes of the attribute add XML configuration

<! -- Cascading attribute assignment -->
<bean id="stark09" class="com.citi.entity.Person">
    <property name="car" ref="JAGUAR"></property>
    <! -- Modify the price of the referenced Car -->
    <property name="car.price" value="400000"></property>
</bean>
Copy the code

Add test code

@Test
public void testAssignCascadeProperty(a){
    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);
}
Copy the code

The console log shows that the price has been successfully changed from 580,000 to 400,000, and the price of the original car in the container has also been changed