Quick Refresh : Spring : BeanFactory, ApplicationContext, Bean Lifecycle, Dependency Injection, Bean Scope, Inner Bean, depends-on, lazy-init, Autowiring


Benefits of Using the Spring Framework:   

  • Spring enables developers to develop enterprise-class applications using POJOs. The benefit of using only POJOs is that you do not need an EJB container product such as an application server but you have the option of using only a robust servlet container such as Tomcat or some commercial product.
  • Spring is organized in a modular fashion. Even though the number of packages and classes are substantial, you have to worry only about the ones you need and ignore the rest.
  • Spring does not reinvent the wheel, instead it truly makes use of some of the existing technologies like several ORM frameworks, logging frameworks, JEE, Quartz and JDK timers, and other view technologies.
  • Testing an application written with Spring is simple because environment-dependent code is moved into this framework. Furthermore, by using JavaBeanstyle POJOs, it becomes easier to use dependency injection for injecting test data.
  • Spring's web framework is a well-designed web MVC framework, which provides a great alternative to web frameworks such as Struts or other over-engineered or less popular web frameworks.
  • Spring provides a convenient API to translate technology-specific exceptions (thrown by JDBC, Hibernate, or JDO, for example) into consistent, unchecked exceptions.
  • Lightweight IoC containers tend to be lightweight, especially when compared to EJB containers, for example. This is beneficial for developing and deploying applications on computers with limited memory and CPU resources.
  • Spring provides a consistent transaction management interface that can scale down to a local transaction (using a single database, for example) and scale up to global transactions (using JTA, for example).

BeanFactory vs ApplicationContext?

Bean Factory
  • Bean instantiation/wiring
Application Context
  • Bean instantiation/wiring
  • Automatic BeanPostProcessor registration
  • Automatic BeanFactoryPostProcessor registration
  • Convenient MessageSource access (for i18n)
  • ApplicationEvent publication
So if you need any of the points presented on the Application Context side, you should use ApplicationContext.
As the ApplicationContext includes all functionality of the BeanFactory, it is generally recommended that it be used in preference to the BeanFactory, except for a few limited situations such as in an Applet, where memory consumption might be critical and a few extra kilobytes might make a difference. However, for most 'typical' enterprise applications and systems, the ApplicationContext is what you will want to use. Versions of Spring 2.0 and above make heavy use of the BeanPostProcessor extension point (to effect proxying and suchlike), and if you are using just a plain BeanFactory then a fair amount of support such as transactions and AOP will not take effect (at least not without some extra steps on your part), which could be confusing because nothing will actually be wrong with the configuration.

What are important ApplicationContext implementations in spring framework?

  • ClassPathXmlApplicationContext – This context loads a context definition from an XML file located in the class path, treating context definition files as class path resources.
  • ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
  • FileSystemXmlApplicationContext – This context loads a context definition from an XML file in the filesystem.
  • ApplicationContext context = new FileSystemXmlApplicationContext("bean.xml");
  • XmlWebApplicationContext – This context loads the context definitions from an XML file contained within a web application. 

Explain Bean lifecycle in Spring framework?

  • The spring container finds the bean’s definition from the XML file and instantiates the bean.
  • Using the dependency injection, spring populates all of the properties as specified in the bean definition.
  • If the bean implements the BeanNameAware interface, the factory calls setBeanName() passing the bean’s ID.
  • If the bean implements the BeanFactoryAware interface, the factory calls setBeanFactory(), passing an instance of itself.
  • If there are any BeanPostProcessors associated with the bean, their postProcessBeforeInitialization() methods will be called.
  • If an init-method is specified for the bean, it will be called.
  • Finally, if there are any BeanPostProcessors associated with the bean, their postProcessAfterInitialization() methods will be called.
Initialization callbacks: The org.springframework.beans.factory.InitializingBean interface specifies a single method −   
                    void afterPropertiesSet() throws Exception;
Thus, you can simply implement the above interface and initialization work can be done inside afterPropertiesSet() method as follows −

public class ExampleBean implements InitializingBean {
   public void afterPropertiesSet() {
      // do some initialization work
   }
}
In the case of XML-based configuration metadata, you can use the init-method attribute to specify the name of the method that has a void no-argument signature. For example −
         <bean id = "exampleBean" class = "examples.ExampleBean" init-method = "init"/>
Following is the class definition −
        public class ExampleBean {
            public void init() {
               // do some initialization work
            }
        }
Destruction callbacks:
The org.springframework.beans.factory.DisposableBean interface specifies a single method −
                         void destroy() throws Exception;
Thus, you can simply implement the above interface and finalization work can be done inside destroy() method as follows −
      public class ExampleBean implements DisposableBean {
           public void destroy() {
               // do some destruction work
           }
      }
In the case of XML-based configuration metadata, you can use the destroy-method attribute to specify the name of the method that has a void no-argument signature. For example −
             <bean id = "exampleBean" class = "examples.ExampleBean" destroy-method = "destroy"/>
Following is the class definition −
       public class ExampleBean {
             public void destroy() {
                // do some destruction work
             }
        }

Default initialization and destroy methods
If you have too many beans having initialization and/or destroy methods with the same name, you don't need to declare init-method and destroy-method on each individual bean. Instead, the framework provides the flexibility to configure such situation using default-init-method and default-destroy-method attributes on the <beans> element as follows −

<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-3.0.xsd"
   default-init-method = "init" 
   default-destroy-method = "destroy">

   <bean id = "..." class = "...">
      <!-- collaborators and configuration for this bean go here -->
   </bean>  

</beans>

BeanPostProcessor: BeanPostProcessor  interface defines callback methods that you can implement to provide your own instantiation logic, dependency-resolution logic, etc. You can also implement some custom logic after the Spring container finishes instantiating, configuring, and initializing a bean by plugging in one or more BeanPostProcessor implementations.

You can configure multiple BeanPostProcessor interfaces and you can control the order in which these BeanPostProcessor interfaces execute by setting the order property provided the BeanPostProcessor implements the Ordered interface.

The BeanPostProcessors operate on bean (or object) instances, which means that the Spring IoC container instantiates a bean instance and then BeanPostProcessor interfaces do their work.


An ApplicationContext automatically detects any beans that are defined with the implementation of the BeanPostProcessor interface and registers these beans as postprocessors, to be then called appropriately by the container upon bean creation.

Example:

public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }
   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
   public void init(){
      System.out.println("Bean is going through init.");
   }
   public void destroy(){
      System.out.println("Bean will destroy now.");
   }

}

public class InitHelloWorld implements BeanPostProcessor {
   public Object postProcessBeforeInitialization(Object bean, String beanName) 
      throws BeansException {
      
      System.out.println("BeforeInitialization : " + beanName);
      return bean;  // you can return any other object as well
   }
   public Object postProcessAfterInitialization(Object bean, String beanName) 
      throws BeansException {
      
      System.out.println("AfterInitialization : " + beanName);
      return bean;  // you can return any other object as well
   }

}

public class MainApp {
   public static void main(String[] args) {
      AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
      obj.getMessage();
      context.registerShutdownHook();
   }

}

Here you need to register a shutdown hook registerShutdownHook() method that is declared on the AbstractApplicationContext class. This will ensures a graceful shutdown and calls the relevant destroy methods.

<?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-3.0.xsd">

   <bean id = "helloWorld" class = "com.dj.HelloWorld"

      init-method = "init" destroy-method = "destroy">
      <property name = "message" value = "Hello World!"/>
   </bean>

   <bean class = "com.dj.InitHelloWorld" />


</beans>

Output:

BeforeInitialization : helloWorld
Bean is going through init.
AfterInitialization : helloWorld
Your Message : Hello World!

Bean will destroy now.

Bean definition inheritance:  

A bean definition can contain a lot of configuration information, including constructor arguments, property values, and container-specific information such as initialization method, static factory method name, and so on.
A child bean definition inherits configuration data from a parent definition. The child definition can override some values, or add others, as needed.

Spring Bean definition inheritance has nothing to do with Java class inheritance but the inheritance concept is same. You can define a parent bean definition as a template and other child beans can inherit the required configuration from the parent bean


<bean id = "helloWorld" class = "com.dj.HelloWorld">

      <property name = "message1" value = "Hello World!"/>
      <property name = "message2" value = "Hello Second World!"/>
   </bean>

   <bean id ="helloIndia" class = "com.dj.HelloIndia" parent = "helloWorld">

      <property name = "message1" value = "Hello India!"/>
      <property name = "message3" value = "Namaste India!"/>
   </bean>

Bean Definition Template: 

You can create a Bean definition template, which can be used by other child bean definitions without putting much effort. While defining a Bean Definition Template, you should not specify the class attribute and should specify abstract attribute and should specify the abstract attribute with a value of true. The parent bean cannot be instantiated on its own because it is incomplete, and it is also explicitly marked as abstract.

   <bean id = "beanTeamplate" abstract = "true">

      <property name = "message1" value = "Hello World!"/>
      <property name = "message2" value = "Hello Second World!"/>
      <property name = "message3" value = "Namaste India!"/>
   </bean>

   <bean id = "helloIndia" class = "com.tutorialspoint.HelloIndia" parent = "beanTeamplate">

      <property name = "message1" value = "Hello India!"/>
      <property name = "message3" value = "Namaste India!"/>

   </bean>

Dependency Injection (DI) 

The technology that Spring is most identified with is the Dependency Injection (DI) flavor of Inversion of Control. The Inversion of Control (IoC) is a general concept, and it can be expressed in many different ways. Dependency Injection is merely one concrete example of Inversion of Control.
When writing a complex Java application, application classes should be as independent as possible of other Java classes to increase the possibility to reuse these classes and to test them independently of other classes while unit testing. Dependency Injection helps in gluing these classes together and at the same time keeping them independent.
What is dependency injection exactly? Let's look at these two words separately. Here the dependency part translates into an association between two classes. For example, class A is dependent of class B. Now, let's look at the second part, injection. All this means is, class B will get injected into class A by the IoC.

Dependency injection can happen in the way of passing parameters to the constructor or by post-construction using setter methods. Two types:
(1)   Constructor Injection: Constructor-based DI is accomplished when the container invokes a class constructor with a number of arguments, each representing a dependency on the other class. Two types -
a.     Constructor Argument Type Matching
b.    Constructor Argument Index
(2)   Setter Injection: Setter-based DI is accomplished by the container calling setter methods on your beans after invoking a no-argument constructor or no-argument static factory method to instantiate your bean.

You can mix both, Constructor-based and Setter-based DI but it is a good rule of thumb to use constructor arguments for mandatory dependencies and setters for optional dependencies.

Bean scopes: The Spring Framework supports exactly five scopes (of which three are available only if you are using a web-aware ApplicationContext). The default scope is always singleton. The scopes supported are listed below:
ScopeDescription
singleton
Scopes a single bean definition to a single object instance per Spring IoC container.
prototype
Scopes a single bean definition to any number of object instances.
request
Scopes a single bean definition to the lifecycle of a single HTTP request;
that is each and every HTTP request
will have its own instance of a bean created off the back of a single bean definition.
Only valid in the context of a web-aware Spring ApplicationContext.
session
Scopes a single bean definition to the lifecycle of a HTTP Session.
Only valid in the context of a web-aware Spring ApplicationContext.
global session
Scopes a single bean definition to the lifecycle of a global HTTP Session.
Typically only valid when used in a portlet context.
Only valid in the context of a web-aware SpringApplicationContext.


What are singleton beans and how can you create prototype beans?

Beans defined in spring framework are by default singleton beans. There is an attribute in bean tag named ‘singleton’ if specified true then bean becomes singleton and if set to false then the bean becomes a prototype bean. By default it is set to true. So, all the beans in spring framework are by default singleton beans.
<beans>
  <bean id="bar" class="com.act.Foo"
      singleton="false"/>
</beans>

Inner beans:

A <bean/> element inside the <property/> or <constructor-arg/> elements is used to define a so-called inner bean. An inner bean definition does not need to have any id or name defined, and it is best not to even specify any id or name value because the id or name value simply will be ignored by the container.
<bean id="outer" class="...">
  <!-- instead of using a reference to a target bean, simply define the target bean inline -->
  <property name="target">
    <bean class="com.example.Person"> <!-- this is the inner bean -->
      <property name="name" value="Fiona Apple"/>
      <property name="age" value="25"/>
    </bean>
  </property>
</bean>
Note that in the specific case of inner beans, the 'scope' flag and any 'id' or 'name' attribute are effectively ignored. Inner beans are always anonymous and they are always scoped as prototypes. Please also note that it is not possible to inject inner beans into collaborating beans other than the enclosing bean.

 Using depends-on :

For most situations, the fact that a bean is a dependency of another is expressed by the fact that one bean is set as a property of another. This is typically accomplished with the <ref/> element in XML-based configuration metadata. For dependencies between beans are less direct (for example, when a static initializer in a class needs to be triggered, such as database driver registration), the 'depends-on' attribute may be used to explicitly force one or more beans to be initialized before the bean using this element is initialized. 

<bean id="beanOne" class="ExampleBean" depends-on="manager"/> 
<bean id="manager" class="ManagerBean" />

If you need to express a dependency on multiple beans, you can supply a list of bean names as the value of the 'depends-on' attribute, with commas, whitespace and semicolons all valid delimiters, like so:
<bean id="beanOne" class="ExampleBean" depends-on="manager,accountDao">
  <property name="manager" ref="manager" />
</bean>
 
<bean id="manager" class="ManagerBean" />
<bean id="accountDao" class="x.y.jdbc.JdbcAccountDao" />

Note: The 'depends-on' attribute at the bean definition level is used not only to specify an initialization time dependency, but also to specify the corresponding destroy time dependency (in the case of singleton beans only). Dependent beans that define a 'depends-on' relationship with a given bean will be destroyed first - prior to the given bean itself being destroyed. As a consequence, 'depends-on' may be used to control shutdown order too.

Lazily-instantiated beans:

The default behavior for ApplicationContext implementations is to eagerly pre-instantiate all singleton beans at startup. Pre-instantiation means that an ApplicationContext will eagerly create and configure all of its singleton beans as part of its initialization process. Generally this is a good thing, because it means that any errors in the configuration or in the surrounding environment will be discovered immediately (as opposed to possibly hours or even days down the line).

However, there are times when this behavior is not what is wanted. If you do not want a singleton bean to be pre-instantiated when using an ApplicationContext, you can selectively control this by marking a bean definition as lazy-initialized. A lazily-initialized bean indicates to the IoC container whether or not a bean instance should be created at startup or when it is first requested.

<bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true"/>

<bean name="not.lazy" class="com.foo.AnotherBean"/>

When the above configuration is consumed by an ApplicationContext, the bean named 'lazy' will not be eagerly pre-instantiated when the ApplicationContext is starting up, whereas the 'not.lazy' bean will be eagerly pre-instantiated.
One thing to understand about lazy-initialization is that even though a bean definition may be marked up as being lazy-initialized, if the lazy-initialized bean is the dependency of a singleton bean that is not lazy-initialized, when the ApplicationContext is eagerly pre-instantiating the singleton, it will have to satisfy all of the singletons dependencies, one of which will be the lazy-initialized bean! So don't be confused if the IoC container creates one of the beans that you have explicitly configured as lazy-initialized at startup; all that means is that the lazy-initialized bean is being injected into a non-lazy-initialized singleton bean elsewhere.
It is also possible to control lazy-initialization at the container level by using the 'default-lazy-init' attribute on the <beans/> element; for example:
<beans default-lazy-init="true">
    <!-- no beans will be pre-instantiated... -->
</beans>

value and ref attribute: 

 configure primitive data type using value attribute and object references using ref attribute of the <property> tag in your Bean configuration file.

if you want to pass plural values like Java Collection types such as List, Set, Map, and Properties.
1 <list> This helps in wiring ie injecting a list of values, allowing duplicates.
2 <set> This helps in wiring a set of values but without any duplicates.
3 <map> This can be used to inject a collection of name-value pairs where name and value can be of any type.
4 <props> This can be used to inject a collection of name-value pairs where the name and value are both Strings.

   <bean id = "..." class = "...">
      <!-- Passing bean reference  for java.util.List -->
      <property name = "addressList">
         <list>
            <ref bean = "address1"/>
            <ref bean = "address2"/>
            <value>Pakistan</value>
         </list>
      </property>
   
      <!-- Passing bean reference  for java.util.Set -->
      <property name = "addressSet">
         <set>
            <ref bean = "address1"/>
            <ref bean = "address2"/>
            <value>Pakistan</value>
         </set>
      </property>
   
      <!-- Passing bean reference  for java.util.Map -->
      <property name = "addressMap">
         <map>
            <entry key = "one" value = "INDIA"/>
            <entry key = "two" value-ref = "address1"/>
            <entry key = "three" value-ref = "address2"/>
         </map>
      </property>
   </bean>

Injecting null and empty string values:
Pass Empty value-
<bean id = "..." class = "exampleBean">
   <property name = "email" value = ""/>
</bean>

Pass a NULL value -

<bean id = "..." class = "exampleBean">
   <property name = "email"><null/></property>
</bean>

Autowiring Mode: 
The Spring container is able to autowire relationships between collaborating beans. This means that it is possible to automatically let Spring resolve collaborators (other beans) for your bean by inspecting the contents of the BeanFactory. The autowiring functionality has five modes. Autowiring is specified per bean and can thus be enabled for some beans, while other beans will not be autowired. Using autowiring, it is possible to reduce or eliminate the need to specify properties or constructor arguments, thus saving a significant amount of typing. When using XML-based configuration metadata, the autowire mode for a bean definition is specified by using the autowire attribute of the <bean/> element.

Mode
Explanation
no
No autowiring at all. Bean references must be defined via a ref element. This is the default, and changing this is discouraged for larger deployments, since explicitly specifying collaborators gives greater control and clarity. To some extent, it is a form of documentation about the structure of a system.
byName
Autowiring by property name. This option will inspect the container and look for a bean named exactly the same as the property which needs to be autowired. For example, if you have a bean definition which is set to autowire by name, and it contains a master property (that is, it has a setMaster(..) method), Spring will look for a bean definition named master, and use it to set the property.
byType
Allows a property to be autowired if there is exactly one bean of the property type in the container. If there is more than one, a fatal exception is thrown, and this indicates that you may not use byType autowiring for that bean. If there are no matching beans, nothing happens; the property is not set. If this is not desirable, setting the dependency-check="objects"attribute value specifies that an error should be thrown in this case.
constructor
This is analogous to byType, but applies to constructor arguments. If there isn't exactly one bean of the constructor argument type in the container, a fatal error is raised.
autodetect
Chooses constructor or byType through introspection of the bean class. Spring first tries to wire using autowire by constructor, if it does not work, Spring tries to autowire by byType.

Limitations with autowiring:
Autowiring works best when it is used consistently across a project. If autowiring is not used in general, it might be confusing for developers to use it to wire only one or two bean definitions. Though autowiring can significantly reduce the need to specify properties or constructor arguments you should consider the limitations and disadvantages of autowiring before using them.

1 Overriding possibility - You can still specify dependencies using <constructor-arg> and <property> settings which will always override autowiring.

2 Primitive data types - You cannot autowire so-called simple properties such as primitives, Strings, and Classes.

3 Confusing nature - Autowiring is less exact than explicit wiring, so if possible prefer using explict wiring.

Spring - Annotation Based Configuration: It is possible to configure the dependency injection using annotations. So instead of using XML to describe a bean wiring, you can move the bean configuration into the component class itself by using annotations on the relevant class, method, or field declaration. Annotation injection is performed before XML injection. Thus, the latter configuration will override the former for properties wired through both approaches.

Annotation wiring is not turned on in the Spring container by default. So, before we can use annotation-based wiring, we will need to enable it in our Spring configuration file.
<context:annotation-config/>

1 @Required  -The @Required annotation applies to bean property setter methods.
2 @Autowired - The @Autowired annotation can apply to bean property setter methods, non-setter methods, constructor and properties
3 @Qualifier - The @Qualifier annotation along with @Autowired can be used to remove the confusion by specifiying which exact bean will be wired.
4 JSR-250 Annotations -Spring supports JSR-250 based annotations which include @Resource, @PostConstruct and @PreDestroy annotations.

Event Handling in Spring: The ApplicationContext publishes certain types of events when loading the beans. For example, a ContextStartedEvent is published when the context is started and ContextStoppedEvent is published when the context is stopped. Event handling in the ApplicationContext is provided through the ApplicationEvent class and ApplicationListener interface. Hence, if a bean implements the ApplicationListener, then every time an ApplicationEvent gets published to the ApplicationContext, that bean is notified. Spring's event handling is single-threaded so if an event is published, until and unless all the receivers get the message, the processes are blocked and the flow will not continue. Hence, care should be taken when designing your application if the event handling is to be used.

Spring provides the following standard events −
1 ContextRefreshedEvent: This event is published when the ApplicationContext is either initialized or refreshed. This can also be raised using the refresh() method on the ConfigurableApplicationContext interface.

2 ContextStartedEvent: This event is published when the ApplicationContext is started using the start() method on the ConfigurableApplicationContext interface. You can poll your database or you can restart any stopped application after receiving this event.

3 ContextStoppedEvent: This event is published when the ApplicationContext is stopped using the stop() method on the ConfigurableApplicationContext interface. You can do required housekeep work after receiving this event.

4 ContextClosedEvent:This event is published when the ApplicationContext is closed using the close() method on the ConfigurableApplicationContext interface. A closed context reaches its end of life; it cannot be refreshed or restarted.

5 RequestHandledEvent:This is a web-specific event telling all beans that an HTTP request has been serviced.

Listening to Context Events: To listen to a context event, a bean should implement the ApplicationListener interface which has just one method onApplicationEvent().

public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }
   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
}

public class CStartEventHandler
   implements ApplicationListener<ContextStartedEvent>{

   public void onApplicationEvent(ContextStartedEvent event) {
      System.out.println("ContextStartedEvent Received");
   }
}

public class CStopEventHandler
   implements ApplicationListener<ContextStoppedEvent>{

   public void onApplicationEvent(ContextStoppedEvent event) {
      System.out.println("ContextStoppedEvent Received");
   }
}

public class MainApp {
   public static void main(String[] args) {
      ConfigurableApplicationContext context =
         new ClassPathXmlApplicationContext("Beans.xml");

      // Let us raise a start event.
      context.start();

      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
      obj.getMessage();

      // Let us raise a stop event.
      context.stop();
   }
}

<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-3.0.xsd">

   <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld">
      <property name = "message" value = "Hello World!"/>
   </bean>

   <bean id = "cStartEventHandler" class = "com.tutorialspoint.CStartEventHandler"/>
   <bean id = "cStopEventHandler" class = "com.tutorialspoint.CStopEventHandler"/>

</beans>

Output:
ContextStartedEvent Received
Your Message : Hello World!
ContextStoppedEvent Received

Custom Events in Spring:
public class CustomEvent extends ApplicationEvent{
   public CustomEvent(Object source) {
      super(source);
   }
   public String toString(){
      return "My Custom Event";
   }
}

public class CustomEventPublisher implements ApplicationEventPublisherAware {
   private ApplicationEventPublisher publisher;
 
   public void setApplicationEventPublisher (ApplicationEventPublisher publisher) {
      this.publisher = publisher;
   }
   public void publish() {
      CustomEvent ce = new CustomEvent(this);
      publisher.publishEvent(ce);
   }
}

public class CustomEventHandler implements ApplicationListener<CustomEvent> {
   public void onApplicationEvent(CustomEvent event) {
      System.out.println(event.toString());
   }
}

public class MainApp {
   public static void main(String[] args) {
      ConfigurableApplicationContext context =
         new ClassPathXmlApplicationContext("Beans.xml");

      CustomEventPublisher cvp =
         (CustomEventPublisher) context.getBean("customEventPublisher");
   
      cvp.publish();
      cvp.publish();
   }
}

<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-3.0.xsd">

   <bean id = "customEventHandler" class = "com.dj.CustomEventHandler"/>
   <bean id = "customEventPublisher" class = "com.dj.CustomEventPublisher"/>

</beans>

output:
My Custom Event
My Custom Event

Comments

Popular posts from this blog

Ashtavinayak Temples | 8 Ganpati Temples of Maharashtra | Details Travel Reviews

Ramoji Film City, Hyderabad, India

Pune to Ganpatipule Trip