Making Your Beans Spring Aware



Using the BeanNameAware Interface


The BeanNameAware interface, which can be implemented by a bean that wants to obtain its own name, has a single method: setBeanName(String). Spring calls the setBeanName() method after it has finished configuring your bean but before any life cycle callbacks (to initialize or destroy) are called. In most cases, the implementation of the setBeanName() interface is just a single line that stores the value passed in by the container in a field for use later on

Implementing BeanNameAware

public class LoggingBean implements BeanNameAware {
private static final Log logger = LogFactory.getLog(LoggingBean.class);
private String name;
public void setBeanName(String name) {
this.name = name;
}
public void run() {
if (logger.isInfoEnabled()) {
logger.info("Bean name " + this.name);
}
}
}

Remember that BeanNameAware.setBeanName() is called before the first instance of the bean is returned to your application via a call to BeanFactory.getBean(), so there is no need to check to see if the bean name is available in the someOperation() method.

Configuring the LoggingBean Example

<?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="logging" class="com.apress.prospring2.ch04.interaction.LoggingBean"/>
</beans>

The LoggingBeanDemo Class

public class LoggingBeanDemo {
public static void main(String[] args) {
XmlBeanFactory factory = new XmlBeanFactory(
new ClassPathResource("/META-INF/spring/interactiondemo-context.xml")
);
LoggingBean lb = (LoggingBean)factory.getBean("logging");
lb.run();
}
}

This example generates the following log output—notice the inclusion of the bean name in the
log message for the call to run():

INFO [main] LoggingBean.run(20) | Bean name is'logging'.


Using the BeanFactoryAware Interface


Using the BeanFactoryAware method, it is possible for your beans to get a reference to the BeanFactory that configured them. The main reason this interface was created was to allow a bean to access other beans programmatically, using getBean().

the BeanFactory isn’t just used to look up beans; it performs a great many other tasks.
As you saw previously, one of these tasks is to destroy all singletons, notifying each of them in turn before doing so. In the previous section, you saw how to create a shutdown hook to ensure that the BeanFactory is instructed to destroy all singletons before the application shuts down. By using the BeanFactoryAware interface, you can build a bean that can be configured in a BeanFactory to create and configure a shutdown hook bean automatically

The ShutdownHookBean Class

public class ShutdownHookBean implements BeanFactoryAware, Runnable {
private static final Log logger = LogFactory.getLog(ShutdownHookBean.class);
private ConfigurableListableBeanFactory beanFactory;
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
if (beanFactory instanceof DefaultListableBeanFactory) {
this.beanFactory = (ConfigurableListableBeanFactory)beanFactory;
Runtime.getRuntime().addShutdownHook(new Thread(this));
}
}
public void run() {
if (this.beanFactory != null) {
logger.info("Destroying singletons.");
this.beanFactory.destroySingletons();
}
}

}

Configuring the ShutdownHookBean Class

<?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="logging" class="com.apress.prospring2.ch04.interaction.LoggingBean"/>
<bean class="com.apress.prospring2.ch04.interaction.ShutdownHookBean"/>

</beans>

Using ShutdownHookBean

public class ShutdownHookBeanDemo {
public static void main(String[] args) {
XmlBeanFactory factory = new XmlBeanFactory(
new ClassPathResource("/META-INF/spring/interactiondemo2-context.xml")
);
factory.preInstantiateSingletons();
LoggingBean lb = (LoggingBean)factory.getBean("logging");
lb.run();
}

This code should seem quite familiar to you, but note that we have included a call to
ConfigurableListableBeanFactory.preInstantiateSingletons(). By default, Spring lazily instantiates singleton beans as they are needed

This is a problem for the ShutdownHookBean, because it needs to be instantiated to register itself as a shutdown hook. Invoking preInstantiateSingletons() causes Spring to run through all its singleton bean definitions and create the instances, invoking any callback

methods as appropriate. Running this example yields the following output, as expected:

INFO [main] XmlBeanDefinitionReader.loadBeanDefinitions(308) | ➥
Loading XML bean definitions from class path resource ➥
[META-INF/spring/interactiondemo2-context.xml]
INFO [main] DefaultListableBeanFactory.preInstantiateSingletons(385) | ➥
Pre-instantiating singletons in org.springframework.beans.factory.xml.➥
XmlBeanFactory@57ae58: defining beans ➥
[logging,com.apress.prospring2.ch04.interaction.ShutdownHookBean#0]; ➥
root of factory hierarchy

INFO [main] LoggingBean.run(20) | Bean name is'logging'.
INFO [Thread-0] ShutdownHookBean.run(27) | Destroying singletons.
INFO [Thread-0] DefaultSingletonBeanRegistry.destroySingletons(340) | ➥
Destroying singletons in org.springframework.beans.factory.xml.➥
XmlBeanFactory@57ae58: defining beans ➥
[logging,com.apress.prospring2.ch04.interaction.ShutdownHookBean#0]; ➥

root of factory hierarchy

Leave a Reply

Subscribe to Posts | Subscribe to Comments

About This Site

Howdy! My name is Suersh Rohan and I am the developer and maintainer of this blog. It mainly consists of my thoughts and opinions on the technologies I learn,use and develop with.

Blog Archive

Powered by Blogger.

- Copyright © My Code Snapshots -Metrominimalist- Powered by Blogger - Designed by Suresh Rohan -