Spring -- thirteen experiments of configuring bean s based on Xml

public class Person {
    private String name;
    private int age;
    private String email;

    public Person() {
    }

    public Person(String name, int age, String email) {
        this.name = name;
        this.age = age;
        this.email = email;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", email='" + email + '\'' +
                '}';
    }
}

Experiment 1: get the bean instance from the IOC container according to the bean type

<bean id = "person01" class="com.shang.core.Person">
        <property name="name" value="lcp"></property>
        <property name="age" value="12"></property>
        <property name="email" value="54372882"></property>
</bean>
<bean id="person02" class="com.shang.core.Person">
        <property name="name" value="Wang Wu"></property>
        <property name="age" value="14"></property>
        <property name="email" value="723683"></property>
</bean>

The property property is actually assigned to the bean through the set method.

When creating two different objects in the same class, you need to use id to distinguish them. If this is the case, you can get the value directly according to the class name

        Person person = ioc.getBean(Person.class);
		//org.springframework.beans.factory.NoUniqueBeanDefinitionException:
        // No qualifying bean of type 'com.shang.core.Person' available:
        // expected single matching bean but found 2: person01,person02

The above error will occur. If you need to use this method to get objects according to classes, you can get them directly

<T> T getBean(String var1, Class<T> var2) throws BeansException;

Experiment 2: assign values to bean s through constructors and p namespaces

In addition to the set method, we can also assign values through the constructor

<!-->key-value</-->
<bean id="person03" class="com.shang.core.Person">
        <constructor-arg name="age" value="12"></constructor-arg>
        <constructor-arg name="name" value="dispersed"></constructor-arg>
        <constructor-arg name="email" value="6372865768"></constructor-arg>
</bean>

<!-->only value,It needs to be configured in the order of the constructor</-->
<bean id="person04" class="com.shang.core.Person">
    <constructor-arg value="Zhang San"></constructor-arg>
    <constructor-arg value="23"></constructor-arg>
    <constructor-arg value="326781"></constructor-arg>
</bean>

<!-->If the order of assignment is wrong, you need to pass index Position the subscript</-->
<bean id="person05" class="com.shang.core.Person">
    <constructor-arg value="6789327292" index="2"></constructor-arg>
    <constructor-arg value="23" index="1"></constructor-arg>
    <constructor-arg value="Internet Bar" index="0"></constructor-arg>
</bean>

The p namespace can reduce the amount of code for simple bean s. Before that, we need to introduce the configuration file

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

usage method

<bean id="person06" class="com.shang.core.Person"
      p:age="12" p:email="37782346892" p:name="Mail received">
</bean>

Experiment 3: assign values to complex types (Object, Map, List) and reference values

1. Assign a value null

If we only register a bean without assignment, all beans are null, but if a member of the bean itself has a value, we need to make the value null.

<!-->private String name = "Zhang San";</-->
<bean id="person01" class="com.shang.core.Person">
    <property name="name">
        <null></null>
    </property>
</bean>

The value of the output name is null

2. Assign value to complex type Car

public class Car {
    private String name;
    private String color;
    private double value;

    public Car() {
    }

    public Car(String name, String color, double value) {
        this.name = name;
        this.color = color;
        this.value = value;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public double getValue() {
        return value;
    }

    public void setValue(double value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Car{" +
                "name='" + name + '\'' +
                ", color='" + color + '\'' +
                ", value=" + value +
                '}';
    }
}

There are two methods. One is to directly generate a beans in the property (equivalent to directly new an object, but even if it has an id, it will not be obtained through getBean()). The other is to reference the existing car object in beanFactory. Because it is a reference relationship, once the value of car is changed, the whole value will be changed.

<bean id="car01" class="com.shang.core.Car">
    <property name="name" value="bmw"></property>
    <property name="color" value="red"></property>
    <property name="value" value="300000"></property>
</bean>

<bean id="person02" class="com.shang.core.Person">
    <property name="car" >
        <bean class="com.shang.core.Car">
            <property name="name" value="hh"></property>
        </bean>
    </property>
</bean>

<bean id="person03" class="com.shang.core.Person">
    <property name="car" ref="car01"></property>
</bean>

3. Assign value to list

One is an internal bean, or a direct reference to an external type

<bean id="book01" class="com.shang.core.Book">
    <property name="name" value="All mail"></property>
</bean>
<bean id="person03" class="com.shang.core.Person">
    <property name="car" ref="car01"></property>
    <property name="bookList">
        <!-- bookList=new ArrayList<Book>();-->
        <list>
            <bean class="com.shang.core.Book" p:name="Journey to the West"></bean>
            <ref bean="book01"></ref>
        </list>
    </property>
</bean>

4. Assign value to map

Like list, it is equivalent to creating a map

<property name="bookMap">
    <map>
        <!--One entry Represents a key value pair-->
        <entry key="key01" value="Li Si"></entry>
        <entry key="key02" value="18"></entry>
        <entry key="key03" value-ref="book01"></entry>
        <entry key="key04">
            <bean class="com.shang.core.Car">
                <property name="name" value="Tesla"></property>
            </bean>
        </entry>
    </map>
</property>

5. bean of collection type

If the collection object can only be configured inside a bean, the configuration of the collection cannot be reused. We need to take the configuration of the collection bean outside for reference by other beans. It is also because map and list types are not used in the outermost configuration

This configuration is required before use

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/util
                           http://www.springframework.org/schema/util/spring-util.xsd">
</beans>
<util:map id="utilMap">
    <entry key="Luban one" value="Ha ha ha"></entry>
    <entry key="Luban two" value="Hey, hey, hey"></entry>
    <entry key="Luban three" value="Interesting"></entry>
    <entry key="Luban four" value="Hum"></entry>
</util:map>

Experiment 4: configure beans created by static factory methods, beans created by instance factory methods, and factorybeans

Required class

public class AirPlane {
    private String jzName;
    private String length;
    private int count;

    public AirPlane() {
    }

    public String getJzName() {
        return jzName;
    }

    public void setJzName(String jzName) {
        this.jzName = jzName;
    }

    public String getLength() {
        return length;
    }

    public void setLength(String length) {
        this.length = length;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    @Override
    public String toString() {
        return "AirPlane{" +
                "jzName='" + jzName + '\'' +
                ", length='" + length + '\'' +
                ", count=" + count +
                '}';
    }
}
public class AirPlaneStaticFactory {
    public static AirPlane getAirPlane(String jzName) {
        AirPlane airPlane = new AirPlane();
        airPlane.setJzName(jzName);
        airPlane.setCount(100);
        airPlane.setLength("1000.m");
        return airPlane;
    }
}
public class AriPlaneInstanceFactory {
    public AirPlane getAirPlane(String jzName) {
        AirPlane airPlane = new AirPlane();
        airPlane.setLength(jzName);
        airPlane.setCount(100);
        airPlane.setLength("1000.m");
        return airPlane;
    }
}

1. Static plant and dynamic plant

Factory mode: the factory helps us create objects. A class that specifically helps us create objects is the factory

Static factory: the factory itself does not need to create objects, but is called through static methods. Object = factory class. Factory method name

Instance factory: the factory itself needs to create an object. Object = new factory class. Factory method name

2. Create bean s through static factory configuration

Class: Specifies the full class name of the static factory

Factory method: Specifies the factory method

Method parameters are set using the construction method

<bean id="airPlane" class="com.shang.factory.AirPlaneStaticFactory"
      factory-method="getAirPlane">
    <constructor-arg value="Li Si"></constructor-arg>
</bean>

3. Configure to create bean s through the instance factory

First configure the instance factory object.

Configure which factory we want to use for the AirPlane we want to create

  • Factory bean: specifies which factory instance to use
  • Factory method: which factory method to use
<bean id="airPlane01" class="com.shang.core.AirPlane"
      factory-bean="ariPlaneInstanceFactory"
      factory-method="getAirPlane">
    <constructor-arg value="Wang Wu"></constructor-arg>
</bean>

4.FactoryBean

FactoryBean is an interface specified by Spring. As long as this interface is implemented, Spring considers it a factory.

public class MyFactoryBeanImpl implements FactoryBean<Book> {

    public Book getObject() throws Exception {
        Book book = new Book();
        book.setName("Journey to the West");
        return book;
    }

    public Class<?> getObjectType() {
        return null;
    }

    public boolean isSingleton() {
        return false;
    }
}
<bean id="MyFactoryBeanImpl" class="com.shang.factory.MyFactoryBeanImpl"></bean>

The Book object is directly obtained. Object creation starts when the Book object is obtained

Experiment 5: reuse bean configuration information through inheritance

If an object has only one item different, you can use parent to inherit that object and modify only the item to be modified

<bean id="person01" class="com.shang.core.Person">
    <property name="name">
        <null></null>
    </property>
</bean>
<bean id="person04" class="com.shang.core.Person" parent="person01">
    <property name="name" value="ah"></property>
</bean>

Experiment 6: create a template bean through the abstract attribute

If this bean is added with the abstract attribute, it can only be used as a template and cannot be obtained

<bean id="person01" class="com.shang.core.Person" abstract="true">
    <property name="name">
        <null></null>
    </property>
</bean>

Experiment 7: dependencies between bean s

Since the loading order of beans is the order of xml configuration, if there are dependencies, you can use dependencies on. It will not be created until the dependent beans are created.

<bean id="person" class="com.shang.core.Person"></bean>
<bean id="car" class="com.shang.core.Car" depends-on="person,book"></bean>
<bean id="book" class="com.shang.core.Book"></bean>

Experiment 8: test the scope of beans and create single instance and multi instance beans respectively

There are four values in scope:

  • prototype: multi instance. It is created every time it is fetched, and a new object will be generated every time it is created

  • Singleton: singleton. If the scope is not set, the singleton will be set by default

  • Session: in the same session, create

  • Request: create the same request

<bean id="book" class="com.shang.core.Book" scope="prototype"></bean>

Experiment 9: creating bean s with lifecycle methods

For the bean s in the container, if they are singleton, they have been created when the container is started. If they are non singleton, they are created only when they are obtained.

When configuring a Bean, you can configure the initialization method and destruction method of the Bean.

Destroy method

Init method initialization method

Single column Bean: (container start) constructor - > initialization method - > destruction method (container close)

Multi instance bean: get bean - > initialize - > container close will not call destroy method

public class Book {
    private String name;

    public Book() {
//        System.out.println("Book is created");
    }

    public void init(){
        System.out.println("Book Created----");
    }

    public void destroy(){
        System.out.println("Book Destroyed----");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                '}';
    }
}

Configure single instance and multi instance

<bean id="book01" class="com.shang.core.Book"
      destroy-method="destroy" init-method="init" scope="singleton">
</bean>

<bean id="book02" class="com.shang.core.Book"
      destroy-method="destroy" init-method="init" scope="prototype">
</bean>

About container closing: you can use the close() method of the ConfigurableApplicationContext class that implements the ApplicationContex interface

ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext();
applicationContext.close();

Experiment 10: test the post processor of bean

① The bean postprocessor allows additional processing of the bean before and after calling the initialization method

② The bean post processor processes all bean instances in the IOC container one by one, rather than a single instance. Its typical application is to check the correctness of bean properties or change bean properties according to specific standards.

③ The bean post processor needs to implement the interface: org.springframework.beans.factory.config.BeanPostProcessor. Before and after the initialization method is called, Spring will pass each bean instance to the following two methods of the above interface: ● postProcessBeforeInitialization(Object, String)

●postProcessAfterInitialization(Object, String)

public class Book {
    private String name;

    public Book() {
//        System.out.println("Book is created");
    }

    public void init(){
        System.out.println("Book Created----");
        setName("Journey to the East");
    }

    public void destroy(){
        System.out.println("Book Destroyed----");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                '}';
    }
}

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

    <bean id="MyBeanPostProcessor" class="com.shang.core.MyBeanPostProcessor"></bean>

    <bean id="book01" class="com.shang.core.Book"
          destroy-method="destroy" init-method="init">
        <property name="name" value="Journey to the West"></property>
    </bean>
</beans>
result:
[book01]Before initialization: [Book{name='Journey to the West'} ] MyBeanPostProcessor
Book Created----
[book01]After initialization: [Book{name='Journey to the East'} ] MyBeanPostProcessor
Book Destroyed----

Summary: life cycle sequence of bean after adding post processor

① Create a bean instance through a constructor or factory method

② Set values for bean properties and references to other beans

③ Pass the bean instance to the postProcessBeforeInitialization() method of the bean post processor

④ Call the initialization method of the bean

⑤ Pass the bean instance to the postProcessAfterInitialization() method of the bean post processor

⑥ Beans can use

⑦ Call the bean when the container is closed

Experiment 11: reference external attribute files

Due to Spring's default singleton mode, we can imagine that one thing needs to exist only in the global: database connection pool

Each database connection pool needs a name, password, path and loading class, which may be frequently modified, so we can put these database configuration information outside and call it when using.

Steps:

  1. Create properties file

The reason for not naming username directly is that username is a keyword in Spring

prop.userName=root
prop.password=root
prop.url=jdbc:mysql:///test
prop.driverClass=com.mysql.jdbc.Driver
  1. Introducing context namespace
xmlns:context="http://www.springframework.org/schema/context"
  1. Specify the location of the properties file
<context:property-placeholder location="classpath:jdbc.properties"/>
  1. . import properties from the properties property file
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
	<property name="user" value="${prop.userName}"/>
	<property name="password" value="${prop.password}"/>
	<property name="jdbcUrl" value="${prop.url}"/>
	<property name="driverClass" value="${prop.driverClass}"/>
</bean>

Experiment 12: automatic assembly based on XML (automatic replication)

For custom classes, if we don't want to assign values directly and link an existing bean (configure one more line), we can adopt automatic assembly.

autowired is used in xml file to realize the automatic assembly of members

Average bean default autowired The value of is false
autowired There are three values:
				byType: Based on member name beanFactory If this class has multiple objects, no injection is performed
				byName: According to members id stay beanFactory Looking for it, id The name must be the same as the member name
				construct: Assemble according to the constructor parameter type. If more than one is found according to the type, do not assemble (too complex, not recommended)
<bean id="person" class="com.shang.core.Person" autowire="byName"></bean>

Experiment 13: [spiel test] (Spring expression Language)

Spring Expression Language, Spring Expression Language, abbreviated as SpEL. Supports runtime queries and can manipulate object graphs. Like EL expressions on JSP pages and OGNL expressions used in struts 2, spiel accesses the object graph according to the attributes defined by JavaBean style getXxx() and setXxx() methods, which is completely in line with our familiar operating habits

1. Basic grammar

Spiel uses #{...} as the delimiter, and all characters in the large box will be considered spiel expressions.

2. Use literal (operator, number)

Integer:<property name="count" value="#{5}"/>
Decimal:<property name="frequency" value="#{89.7}"/>
Scientific counting method:<property name="capacity" value="#{1e4}"/>
String The literal of type can use single quotation marks or double quotation marks as the delimitation symbol of string
	<property name="name" value="#{'Chuck'}"/>
	<property name="name" value='#{"Chuck"}'/>
Boolean: <property name="enabled" value="#{false}"/>

3. Reference other bean s

<property name="car" value="#{car01}"></property>

4. Reference the attribute value of other bean s as the value of one of their own attributes

<property name="car" value="#{car01.name}"></property>

5. Call non static methods

<bean id="book01" class="com.shang.core.Book">
	<property name="name" value="hhh"></property>
</bean>

<bean id="person" class="com.shang.core.Person">
	<property name="name" value="#{book01.getName()}" 
</bean>

5. Call static method

<bean id="employee" class="com.atguigu.spel.bean.Employee">
<!-- stay SpEL Static method for calling class in expression -->
<property name="circle" value="#{T(java.lang.Math).PI*20}"/>
</bean

Tags: Java Spring xml

Posted on Mon, 29 Nov 2021 08:12:50 -0500 by JustLikeIcarus