Spring ReaderEventListener Example

0

In this article, we will show you how one can be notified when a component, alias and an import context is registered during a bean definition reading process.

Dependencies

Add the following dependencies:

  1. spring-core
  2. spring-context
  3. spring-beans

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.javarticles.jdbc.datasource</groupId>
	<artifactId>springdatasource</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>${spring.version}</version>
		</dependency>
	</dependencies>

	<properties>
		<spring.version>3.2.3.RELEASE</spring.version>
	</properties>

</project>

Sample Bean

Our sample bean consists of an inner bean which is of the same type and a string value. It also has myInit() and myDestroy() to be called as the container instantiates or destroys the bean.

TestBean:

package com.javarticles.spring;

public class TestBean {
    private TestBean innerBean;
    private String value;
    public TestBean(){}
    public TestBean(String value) {
        this.value = value;
    }
    public String getValue() {
        return value;
    }
    public TestBean getInnerBean() {
        return innerBean;
    }
    public void setValue(String value) {
        this.value = value;
    }    
    public void myDestroy() {
        System.out.println("myDestroy called for TestBean(" + value + ")");
    }
    public void myInit() {
        System.out.println("myInit called for TestBean(" + value + ")");
    }
    public void setInnerBean(TestBean innerBean) {
        this.innerBean = innerBean;
    }
    
}

Application Context

applicationContext.xml:

<?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"
	default-lazy-init="true" default-autowire="constructor"
	default-init-method="myInit" default-destroy-method="myDestroy"
	default-merge="true">

	<import resource="importContext.xml" />

	<alias name="testBean" alias="alias1" />

	<alias name="testBean" alias="alias2" />

	<bean id="testBean" class="com.javarticles.spring.TestBean">
		<constructor-arg type="java.lang.String" value="A" />
		<property name="innerBean">
			<ref bean="testBean2" />
		</property>
	</bean>

	<bean id="testBean2" class="com.javarticles.spring.TestBean">
		<property name="value" value="C" />
		<property name="innerBean">
			<bean class="com.javarticles.spring.TestBean">
				<property name="value" value="D" />
			</bean>
		</property>
	</bean>
</beans>

importContext.xml:

<?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"
	default-lazy-init="true" default-autowire="byType"
	default-init-method="myInit" default-destroy-method="myDestroy"
	default-merge="false">
	<bean id="testBean3" class="com.javarticles.spring.TestBean">
		<property name="value" value="E"/>
	</bean>	
</beans>

Custom ReaderEventListener

MyReaderEventListener:

package com.javarticles.spring;

import org.springframework.beans.factory.parsing.AliasDefinition;
import org.springframework.beans.factory.parsing.ComponentDefinition;
import org.springframework.beans.factory.parsing.DefaultsDefinition;
import org.springframework.beans.factory.parsing.ImportDefinition;
import org.springframework.beans.factory.parsing.ReaderEventListener;
import org.springframework.beans.factory.xml.DocumentDefaultsDefinition;

public class MyReaderEventListener implements ReaderEventListener {

    public void defaultsRegistered(DefaultsDefinition defaultsDefinition) {
        DocumentDefaultsDefinition defaults = (DocumentDefaultsDefinition) defaultsDefinition;
        System.out.println("Default attributes registered: "
                + "autowire: " + defaults.getAutowire() + ", " 
                + "autowire-candidats: " + defaults.getAutowireCandidates() + ", " 
                + "destroy-method: " + defaults.getDestroyMethod() + ", "
                + "init-method: " + defaults.getInitMethod() + ", "
                + "lazy-init: " + defaults.getLazyInit() + ", " 
                + "merge: " + defaults.getMerge());
    }

    public void componentRegistered(ComponentDefinition componentDefinition) {
        System.out.println("Component Registered: "
                + componentDefinition.getName());
    }

    public void aliasRegistered(AliasDefinition aliasDefinition) {
        System.out.println("Alias Registered: " + aliasDefinition.getAlias());
    }

    public void importProcessed(ImportDefinition importDefinition) {
        System.out.println("Import processed: "
                + importDefinition.getImportedResource());
    }
}

Event Publication Example

  1. Create the bean factory.
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    
  2. Create XML reader.You need to pass the above bean factory so that the beans get registered as they are parsed.
     XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
    
  3. Create ReadEventListener and set it to the reader.
    ReaderEventListener eventListener = new MyReaderEventListener();
    reader.setEventListener(eventListener);
    
  4. Load the context.
    reader.loadBeanDefinitions("applicationContext.xml");
    
  5. Get testBean.
    TestBean testBean = (TestBean) beanFactory.getBean("testBean");
    
  6. Destroy the testBean.
    beanFactory.destroyBean("testBean", testBean);
    

EventPublicationExample:

package com.javarticles.spring;

import org.springframework.beans.factory.parsing.ReaderEventListener;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;

public class EventPublicationExample {
    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
        ReaderEventListener eventListener = new MyReaderEventListener();
        reader.setEventListener(eventListener);
        reader.loadBeanDefinitions("applicationContext.xml");
        TestBean testBean = (TestBean) beanFactory.getBean("testBean");
        beanFactory.destroyBean("testBean", testBean);
    }
}

Output:

May 13, 2015 5:24:59 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
Default attributes registered: autowire: constructor, autowire-candidats: null, destroy-method: myDestroy, init-method: myInit, lazy-init: true, merge: true
May 13, 2015 5:25:00 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [importContext.xml]
Default attributes registered: autowire: byType, autowire-candidats: null, destroy-method: myDestroy, init-method: myInit, lazy-init: true, merge: false
Component Registered: testBean3
Import processed: importContext.xml
Alias Registered: alias1
Alias Registered: alias2
Component Registered: testBean
Component Registered: testBean2
myInit called for TestBean(D)
myInit called for TestBean(C)
myInit called for TestBean(A)
myDestroy called for TestBean(A)

Download the source code

This was an example about custom ReadEventListener. You can download the source code here: springEventPublicationExample.zip

Share.

Comments are closed.