Spring container extension

Posted by rpadilla on Sat, 29 Jan 2022 08:41:03 +0100

------------Restore content start------------

1, BeanPostProcessor

BeanPostProcessor is an extension interface provided by an IOC container to extend the functions of the IOC container. The function of this interface is to add some processing logic before and after the initialization method of the bean is executed after the spring container instantiates the bean. The initialization methods here refer to some default or customized initialization methods of beans.

Interface code display:

public interface BeanPostProcessor {
    //bean Called before initialization method call (preprocessing)
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
    //bean Called after the initialization method is called (post-processing)
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

Working time of the method:

 

The method of using this interface is:

Step 1: define a class, implement the interface and implement the two methods in the interface. Note that the final return value of these two methods must be beans, otherwise the subsequent processing will fail to obtain beans, resulting in errors.

Step 2: configure this class in the xml file and configure it as a bean.

This configuration will work on all bean s in a container

Code example:

Implement the BeanPostProcessor interface:

package scripting;

import org.springframework.beans.factory.config.BeanPostProcessor;

public class InstantiationTracingBeanPostProcessor implements BeanPostProcessor {

    // simply return the instantiated bean as-is
  //Note that the return value must be a bean public Object postProcessBeforeInitialization(Object bean, String beanName) { return bean; // we could potentially return any object reference here... } public Object postProcessAfterInitialization(Object bean, String beanName) { System.out.println("Bean '" + beanName + "' created : " + bean.toString()); return bean; } }

xml configuration

<lang:groovy id="messenger"
            script-source="classpath:org/springframework/scripting/groovy/Messenger.groovy">
        <lang:property name="message" value="Fiona Apple Is Just So Dreamy."/>
    </lang:groovy>

    <!--
    when the above bean (messenger) is instantiated, this custom
    BeanPostProcessor implementation will output the fact to the system console
    -->
    <bean class="scripting.InstantiationTracingBeanPostProcessor"/>

When configuring the Bean of the BeanPostProcessor implementation class, you don't even need to set the id

Test:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.scripting.Messenger;

public final class Boot {

    public static void main(final String[] args) throws Exception {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("scripting/beans.xml");
        Messenger messenger = ctx.getBean("messenger", Messenger.class);
        System.out.println(messenger);
    }

}

Output:

Bean 'messenger' created : org.springframework.scripting.groovy.GroovyMessenger@272961
org.springframework.scripting.groovy.GroovyMessenger@272961

 

 

2, Beanfactoryprocessor

You can dynamically modify the bean configuration in the xml file at run time

By implementing this interface, you can modify the definition properties of spring beans before they are created. In other words, spring allows beanfactoryprocessor to read the configuration metadata before the container instantiates any other bean and modify it as needed. For example, you can change the scope of the bean from singleton to prototype, or modify the value of property. Multiple beanfactoryprocessors can be configured at the same time, and the execution order of each beanfactoryprocessor can be controlled by setting the 'order' attribute.
Note: beanfactoryprocessor is executed before bean instantiation after the spring container loads the bean definition file. The input parameter of the interface method is configurablelistablebeanfactory. Using this parameter, you can get the definition information of relevant beans.

Spring provides some implementation classes of BeanFactoryPostProcessor interface, such as PropertySourcesPlaceholderConfigurer. The property values in the bean definition can be externalized into a separate file using the standard Java format PropertySourcesPlaceholderConfigurer. Properties this enables the person deploying the application to customize environment specific properties, such as database URL s and passwords, without modifying the container's main XML definition file or the complexity or risk of the file.

Example code:

<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
    <property name="locations" value="classpath:com/something/jdbc.properties"/>
</bean>

<bean id="dataSource" destroy-method="close"
        class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

 

properties file:

jdbc.driverClassName=org.hsqldb.jdbcDriver 
jdbc.url=jdbc:hsqldb:hsql://production:9002 
jdbc.username=sa 
jdbc.password=root

 

 

 

 

------------End of recovery------------