Talk about the special relationship between Spring Beans

In the Spring container, in addition to <ref>establishing , there are also some special relationships.

1 Inheritance

In object-oriented programming principles, when multiple classes have the same methods and properties, a parent class can be introduced to eliminate duplicate code. In the Spring container, if multiple beans have the same configuration information, we can define a parent bean, so that the child bean will automatically inherit the configuration information of the parent bean.

<!-- 父 Bean-->
<bean id="abstractBook" class="net.deniro.spring4.bean.Book"
      p:name="面纱" abstract="true">
</bean>
<!-- 子 Bean-->
<bean id="book1" class="net.deniro.spring4.bean.Book"
      p:press="重庆出版社" parent="abstractBook"/>
<bean id="book2" class="net.deniro.spring4.bean.Book"
      p:press="上海译文出版社" parent="abstractBook"/>

In general, the function of the parent bean is to simplify the configuration of the child bean, so it is set to an abstract class ( abstract="true"); if the parent bean is not set to an abstract class, the Spring container will instantiate the parent bean.

2 Pre-dependencies

In general, use <ref>to establish dependencies between beans, and the Spring container is responsible for managing these relationships. When instantiating a bean, the container ensures that the beans that the bean depends on have completed the initialization work.

But in some cases, the dependencies between beans are not so obvious.

Assuming such a scenario, a system sets some system parameters (such as password validity period, whether to enable monitoring, etc.). These startup parameters are used to control the operation logic of the system. We use a Setting class to represent these parameters:

public class Settings {

    /**
     * 密码过期时间(单位:天)
     */
    public static int PASS_TIMEOUT = 30;

    /**
     * 是否开启监控
     */
    public static boolean IS_MONITOR = false;
}

Here, we set default values ​​for these parameters. The system also has a management background, through which the administrator can adjust these system parameters and save them in the database. So when the application starts, these system parameters need to be loaded from the database:

public class System {

    public System() {
        init();
    }

    /**
     * 初始化
     */
    private void init() {
        //假设这些值来源于数据库
        Settings.PASS_TIMEOUT = 20;
        Settings.IS_MONITOR = true;
    }
}

The system has a password expiration manager, which will create a scheduled task to detect whether the password has expired according to the [number of days of password expiration] in the system parameters:

public class PassManager {

    int timeout;

    public PassManager() {
        timeout = Settings.PASS_TIMEOUT;
        timerTask();
    }

    /**
     * 检测密码是否过期的定时任务
     */
    private void timerTask() {
    }

    public int getTimeout() {
        return timeout;
    }
}

Although PassManager does not directly depend on Settings, logically, PassManager expects System to load initialization system parameters before starting.

In Spring, you can explicitly specify the pre-dependent bean of a bean through the depends-on attribute to ensure that the pre-dependent bean has been loaded before the bean is instantiated.

<bean id="system" class="net.deniro.spring4.bean.System"/>
<bean id="manager" class="net.deniro.spring4.bean.PassManager"
      depends-on="system"/>

If the prefix depends on multiple beans, the bean name can be configured by comma, space or semicolon.

3 Reference ID

Suppose a bean needs to refer to another bean's id value (beanName), which is generally used in the context of obtaining another bean through the getBean(beanName) method in the bean at runtime.

It can be configured like this:

<bean id="author" class="net.deniro.spring4.bean.Author"/>
<bean id="book" class="net.deniro.spring4.bean.Book"
      p:authorId="author"/>

New authorId property in Book:

/**
 * author Bean 的 ID
 */
private String authorId;

While it can be set in this literal form, there is no real reference relationship between the two. So the configuration error will only be discovered when the specific call is made.

Spring provides an <idref>element tag, which <idref>refers to the name of another bean, so that when the container starts, the correctness of the reference relationship will be checked, and incorrect configuration information can be found in advance.

<bean id="author10" class="net.deniro.spring4.bean.Author"/>
<bean id="book10" class="net.deniro.spring4.bean.Book"
        >
    <property name="authorId">
        <idref bean="author10"/>
    </property>
</bean>

If there is an error in the configuration, a BeanDefinitionStoreException will be thrown when the Spring container starts, and the XML parser of the IDE will also detect the reference error in advance, so it is recommended to use the element tag to reference the ID.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325811955&siteId=291194637