Chapter 02 – Spring IoC Container Bean Fancy Registration and Retrieval

Fancy 4: Implement Bean registration through inheritance

Add an XML configuration to assign_value.xml that inherits configuration information from other beans using the parent attribute

<! -- Inherit configuration information -->
<bean id="stark10" class="com.citi.entity.Person">
    <property name="lastName" value="stark10"></property>
    <property name="age" value="18"></property>
    <property name="gender" value="Male"></property>
    <property name="email" value="[email protected]"></property>
</bean>

<! -- Inherit stark10 configuration information -->
<bean id="stark11" class="com.citi.entity.Person" parent="stark10">
    <property name="lastName" value="stark11"></property>
</bean>
Copy the code

Add test methods

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

    Person stark11 = context.getBean("stark11",Person.class);
    Person stark10 = context.getBean("stark10",Person.class);

    System.out.println(stark10);
    System.out.println(stark11);
}
Copy the code

Execute the test, except for the name, the message gender and other information is inherited from Stark10

Using the abstract attribute to turn the bean configuration into a configuration template that can only be used to inherit configuration information and cannot be directly retrieved by modifying the XML configuration to add abstract= “true”.

<bean id="stark10" class="com.citi.entity.Person" abstract="true">
    <property name="lastName" value="stark10"></property>
    <property name="age" value="18"></property>
    <property name="gender" value="Male"></property>
    <property name="email" value="[email protected]"></property>
</bean>
Copy the code

Run the test again, error obtaining stark10, stark01 has been marked as abstarct, can only be used for other bean inheritance configuration information

Trick 5: Implement registration of beans that depend on each other

Add a no-argument constructor to the Car, Book, and Person entity classes and print a sentence

System.out.println(this.getClass().getName() + "No argument constructor called");
Copy the code

Create an XML configuration of a bean – Dependency_bean.xml


      
<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">

    <bean id="person" class="com.citi.entity.Person"></bean>
    <bean id="car" class="com.citi.entity.Car"></bean>
    <bean id="book" class="com.citi.entity.Book"></bean>
</beans>
Copy the code

Add new test classes and test methods

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

    String[] beanDefinitionNames = context.getBeanDefinitionNames();
    for(String beanDefinitionName : beanDefinitionNames) { System.out.println(beanDefinitionName); }}Copy the code

Beans are created in the same order as configured in XML

To change the order, you can also use the depends-on tag

<bean id="person" class="com.citi.entity.Person" depends-on="car,book"></bean>
<bean id="car" class="com.citi.entity.Car"></bean>
<bean id="book" class="com.citi.entity.Book"></bean>
Copy the code

The test was executed to create the dependent car,book, and person first

Fancy 6: Implement registration of multi-instance beans

Bean registration is singleton by default, and creating a multi-instance bean requires the addition of the Prototype attribute

Added the singleton_prototype_bean.xml configuration file


      
<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">

    <bean id="person" class="com.citi.entity.Person"></bean>
    <bean id="car" class="com.citi.entity.Car"></bean>
    <bean id="book" class="com.citi.entity.Book"></bean>
</beans>
Copy the code

Add test classes and test methods

public class SingletonPrototypeBeanTest {

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

        System.out.println("IoC container created");
        String[] beanDefinitionNames = context.getBeanDefinitionNames();
        for(String beanDefinitionName : beanDefinitionNames) { System.out.println(beanDefinitionName); }}}Copy the code

Execute the test method and the single-instance bean is created before the container is created

Add the Scope attribute to Person to make it multi-instance

<bean id="person" scope="prototype" class="com.citi.entity.Person"></bean>
Copy the code

Modify test code

public class SingletonPrototypeBeanTest {

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

        System.out.println("IoC container created"); Person p1 = context.getBean(Person.class); Person p2 = context.getBean(Person.class); System.out.println(p1 == p2); }}Copy the code

To test, the multi-instance beans are created after the container is created, and the memory address of the multi-instance beans is not the same

The scope property also has two values, request and session, which are rarely used

Fancy 7: Factory creates the Bean

Factories are divided into static factories and instance factories

  • Static factory: Instead of creating the Bean itself, the factory calls the object = factory class through static methods. Factory method name
  • Instance Factory: The factory itself needs to create the Bean, and obtains the instance factory object from the factory object by first creating a factory object factory class factory object = new Factory class ().getBean()

Added Tesla entity class to entity package

public class Tesla {

    private String name;
    private String battery; / / battery
    private String engine; / / motor
    private String chassis; / / chassis
    private String bodywork; / / body
    private String owner; / / the owner
    // Omit getter/setter/toString methods here
}    
Copy the code

Added facotry package to create static factory and instance factory classes

public class TeslaInstanceFactory {

    public Tesla getTesla(String owner){
        System.out.println("TeslaInstanceFactory called");
        Tesla tesla = new Tesla();
        tesla.setName("Model 3");
        tesla.setBattery("4680");
        tesla.setOwner(owner);

        returntesla; }}Copy the code
public class TeslaStaticFactory {

    public static Tesla getTesla(String owner){
        System.out.println("TeslaStaticFactory called");
        Tesla tesla = new Tesla();
        tesla.setName("Model3");
        tesla.setBattery("4680");
        tesla.setOwner(owner);

        returntesla; }}Copy the code

The static factory creates the Bean

Create configuration information for a static factory in factory.xml


      
<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">

    <! Class: specifies the full class name of the static factory class. factory-method: specifies which method to create the Tesla bean constructor-arg: Use setter methods to assign values -->
    <bean id="model3" class="com.citi.factory.TeslaStaticFactory" factory-method="getTesla">
        <! GetTesla = getTesla = getTesla
        <constructor-arg value="musk1"></constructor-arg>
    </bean>
    
</beans>    
Copy the code

Create a test class FactoryTest, new test methods testGetBeanByStaticFactory ()

public class FactoryTest {

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

        System.out.println("IoC container created");

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

After executing the test method, the console output reads as follows: Tesla Bean created successfully

Instance factory common beans

Add configuration for instance factory creation beans in factory.xml

<bean id="ShanghaiGigaFactory" class="com.citi.factory.TeslaInstanceFactory" >
</bean>

<bean id="modelS" class="com.citi.entity.Tesla" factory-bean="ShanghaiGigaFactory" factory-method="getTesla">
    <! GetTesla = getTesla = getTesla
    <constructor-arg value="musk2"></constructor-arg>
</bean>
Copy the code

Add test methods

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

    System.out.println("IoC container created");

    String[] beanDefinitionNames = context.getBeanDefinitionNames();
    for (String beanDefinitionName : beanDefinitionNames) {
        System.out.println(beanDefinitionName);
    }

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

The console successfully prints modelS Implement the FactoryBean interface to create beansAdd a FactorBean implementation class, BerlinGigaFactoryBean, whose generic type is the type to be created

public class BerlinGigaFactoryBean implements FactoryBean<Tesla> {

    // Returns the created object
    @Override
    public Tesla getObject(a) throws Exception {
        System.out.println("Implement the FactoryBean interface to create beans");
        Tesla tesla = new Tesla();
        tesla.setName("Cybertruck");
        return tesla;
    }

    // Return common types
    @Override
    publicClass<? > getObjectType() {return Tesla.class;
    }

    // Whether it is singleton. The default mode is not singleton
    @Override
    public boolean isSingleton(a) {
        return false; }}Copy the code

Add configuration to factory.xml

<! - implement FactoryBean interface to create Bean configuration file - > < Bean id = "BerlinGigaFactory" class = "com. Citi. Factory. BerlinGigaFactoryBean" > < / Bean >Copy the code

Add test methods

@Test public void testGetBeanByImplFactoryBean() throws Exception { ApplicationContext context = new ClassPathXmlApplicationContext("classpath:factory.xml"); System.out.println("IoC container created "); String[] beanDefinitionNames = context.getBeanDefinitionNames(); for (String beanDefinitionName : beanDefinitionNames) { System.out.println(beanDefinitionName); } Tesla cybertruck = (Tesla) context.getBean("berlinGigaFactory"); System.out.println(cybertruck); }Copy the code

Tesla Bean CyberTruck can be obtained by executing the test method and directly obtaining an instance implementing the FactoryBean interfaceImplement the FactoryBean interface to create beans. The Bean is only created when it is retrieved from the container, regardless of whether it is a singleton in a method.

The BeanFactory interface is the top-level interface of the container. ApplicationContext implements this interface indirectly. You can get beans from the container using the getBean() method.