Spring & Hibernate
====================================
- Framework for building java applications
- Initially it was a lightweight alternative to J2EE
- It provides a large no of helper classes which makes things easier.
In J2EE
------------
Client Server Server
Side <----> Side <----> Side <----> Database
Presentation Presentation Business Logic
(JSP,Servlet,XML (Enterprise Java Beans
Web Services) Web Services)
LifeLine of J2EE
------------------------------
1999 2001 2003 2006 2009 2013 2016/17
------ ------- ------ ------- ------ --------- --------
J2EE 1.2 J2EE 1.3 J2EE 1.4 Java EE 5 Java EE 6 Java EE 7 Java EE 8
Servlet EJB Web Ease of Use Pruning JMS2
JSP CMP Services EJB 3 Ease of Use Batch
EJB JCA Mgmt JPA JAX-RS TX
JMS Deployment JSF CDI Concurrency
RMI JAXB Bean-Validation Web Sockets
JAX-WS
EJB - Enterprise JAVA Beans
JMS - Java Message Service
RMI - Remote Method Invocation
CMP - Container Managed Persistence
JCA - Java Connector Architecture
JPA - Java Persistance API
JSF - Java Server Faces
JAXB - Java API for XML Binding
JAX-WS - Java Web Services (SOAP)
JAX-RS - Java Web Services (REST)
CDI - Context Dependency Injection (IoC)
- Early versions of EJB (version 1 and 2) were extermly complex, XML deployment descriptors were needed, had to define multiple interfaces, so complex and had poor performance while building an EE application.
- Rod JohnSon - Founder Of Spring
Lifeline of Spring
---------------------------
2004 2006 2009 2013 2016(March) 2017 (September)
------- ------- ------ ------ ---------------- ----------------
Spring 1.0 Spring 2.0 Spring 3.0 Spring 4.0 Spring 4.3 Spring 5
Spring 5
================
- Must use JAVA8 or Higher version needed
- Deprecated legacy integration for Tiles, Velocity, Portlet, Guava etc
- Use Upgraded verison of Servlet API 4.0
- New Reactive Programming Framework - Spring Webflux
WWW.spring.io - Official Website
Goals of Spring
--------------------
- LightWeight development with Java POJOs
- Dependency injection to Promote loose coupling
- Declarative Programming with Aspect Oriented Programming (AOP)
- Minimize boilerplate Java Code
Core Container
=========================
Beans
Core
SpEL (Spring Expression Language)
Context
- Core container is the main, the main item of spring
- It manages how the Beans are created.
- It has a bean factory for creating Beans
- It can reconfig files for setting properties, independencies
- It holds the Beans in memory.
Primary Functions
--------------------------
1. Create and manage objects (Inversion of Control)
2. Inject Objects Dependencies (Dependency Injection)
Infrastructure
===============================
AOP(Aspect Oriented Programming)
Aspects
Instrumentation
Messaging
- It adds functionality to objects declaratively
like logging, security, transactions etc...
- It allowsa you to create these applicationwide services
- No need to change the code, just add a config file or an annotation and that service will be applied to your application.
Data Access Layer
================================
JDBC
ORM
Transactions
OXM JMS
- ORM - Object to Relational Mapping (Hibernate/JPA)
Web Layer (Spring MVC)
==========================
Servlet
WebSocket
Web
Portlet
Test Layer
==================
Unit
Integration
Mock
There are Spring projects like
---------------------------------------
Spring Cloud, Spring Data
Spring Batch, Spring Security
Spring Android, Spring Web Flow
Spring Web Services, Spring LDAP
...etc
Requirements
======================
- JDK8 or Higher
- Eclipse IDE
- Tomcat Server
Do This
================
1. Download Tomcat 9.0 and Eclipse IDE and add the server to the IDE in server tab side to console tab.
2. Create an Eclipse Project
3. Download the Spring JAR files
(www.luv2code.com/downloadspring) OR from
https://repo.spring.io/release/org/springframework/spring
And Select the latest one
and select the Release-dist.zip
4. Unzip it and copy all the JAR files from lib folder
5. Go to Eclipse, Create a folder in the project named lib and paste all the JAR files in that folder.
6. Right Click on Project --> Properties --> Java build Path --> Libraries --> classpath --> Add JARS --> Select lib folder --> Select all the JAR files --> OK --> Apply --> Apply and Close --> Check the Referenced Libraries
**********************
Q. Why Spring is lightweight
Spring, on the other hand, is lightweight because it allows minimally invasive development with POJOs. A lightweight framework makes itself as invisible as possible. ... As others have already pointed out, Spring is considered lightweight compared to traditional Java EE applications.
Q. Why Spring is Loosely Coupled
Tight coupling is when a group of classes are highly dependent on one another.
This scenario arises when a class assumes too many responsibilities, or when one concern is spread over many classes rather than having its own class.
Loose coupling is achieved by means of a design that promotes single-responsibility and separation of concerns.
A loosely-coupled class can be consumed and tested independently of other (concrete) classes.
Interfaces are a powerful tool to use for decoupling. Classes can communicate through interfaces rather than other concrete classes, and any class can be on the other end of that communication simply by implementing the interface.
Loose coupling is the approach in which components of an application are interconnected to each other in least dependent way. ... In Spring Framework loose coupling is achieved by a core feature called Dependency Injection and IoC container. In dependency injection, components define their own dependencies when they need.
Q. Why spring is Aspect Oriented Programming
An aspect is a common feature that's typically scattered across methods, classes, object hierarchies, or even entire object models. It is behavior that looks and smells like it should have structure, but you can't find a way to express this structure in code with traditional object-oriented techniques.
Spring AOP enables Aspect-Oriented Programming in spring applications. In AOP, aspects enable the modularization of concerns such as transaction management, logging or security that cut across multiple types and objects (often termed crosscutting concerns).
***********************
Spring Inversion Of Control (IoC)
===============================================
- It is design process of externalizing, the construction and the management of your objects, in other words it is approach of outsourcing the construction and management of Objects. The outsourcing will be handled by a Object Factory.
1_Spring_Demo Created
===============================
1. A package demo is created and BaseballCoach.java Created in the package
package demo;
public class BaseballCoach implements Coach
{
@Override
public String getDailyWorkout()
{
return "Spent 30 Minutes on BaseBall";
}
}
2. Test.java Created
package demo;
// Main Program
public class Test
{
public static void main(String[] args)
{
//Create the object
Coach theCoach = new BadmintonCoach();
//use the object and print the message
System.out.println(theCoach.getDailyWorkout());
}
}
3. Coach.java interface created
package demo;
public interface Coach
{
public String getDailyWorkout();
}
4. BadmintonCoach.java class Created
package demo;
public class BadmintonCoach implements Coach
{
@Override
public String getDailyWorkout()
{
return "Spent 2 Hours on Badminton";
}
}
=================================================================================
- On Test.java at object creation, it is hardcoded. Means if we create object of BadmintonCoach, it will get executed, if we create the object of BaseballCoach, it will get executed. But we have to do it on our own.
- To overcome this situation, Spring is gonna help us.
Primary Functions
--------------------------
1. Create and manage objects (Inversion of Control)
2. Inject Objects Dependencies (Dependency Injection)
- There are 3 ways to configure a Spring container
1. XML configuration file (leagacy)
2. Java Annotation (modern)
3. Java Source Code (modern)
Spring Development Process
==================================
1. Configure Spring Beans
2. Create a Spring Container
3. Retrieve Beans from Spring Container
1. Configure Spring Beans
----------------------------------
Creation of an XML file
XML startup file code
-------------------------------
applicationContext.xml
--------------------------------
2. Create a Spring Container
------------------------------------
- Spring container is generally known as ApplicationContext
- they have specialized implementation for it
- ClassPathXMLApplicationContext - for reading XML form classpath
- AnnotationConfigApplicationContext - for reading annotation configuration
- GenericWebApplicationContext -
...etc
syntax
----------
Present in (org.springframework.context.support.ClassPathXmlApplicationContext)
ClassPathXMLApplicationContext context = new ClassPathXMLApplicationContext("applicationContext.xml")
3. Retrieve Beans from Spring Container
-----------------------------------------------------
syntax
--------------
Class_name object_name = context.getBean(bean_id, class_name)
- bean_id must match the id in xml file
- class_name must match the interface that the class in XMl implements
===============================================================================
In 1_Spring_Demo
----------------------------
5. Create a XML file in src folder applicationContext.xml and write this first
now define your bean like this
6. Create SpringTest.java and do this
package demo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
//Main Class for Spring Test
public class SpringTest
{
public static void main(String[] args)
{
//load the spring configuration file or create and add file into a spring container
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//retrieve the bean from spring container
Coach theCoach = context.getBean("myCoach", Coach.class);
//call methods on the bean
System.out.println(theCoach.getDailyWorkout());
//close the context
context.close();
}
}
7. Run SpringTest.java as Java Application
- Advantage is, you do not need to change the source code each and every time, only change in the configuration file i.e, XML file and it will do the work for you.
Question
----------------------
Why do we specify the Coach interface in getBean()?
For example:
-----------------------
Coach theCoach = context.getBean("myCoach", Coach.class);
Answer
----------------------------
When we pass the interface to the method, behind the scenes Spring will cast the object for you.
context.getBean("myCoach", Coach.class)
However, there are some slight differences than normal casting.
From the Spring docs:
Behaves the same as getBean(String), but provides a measure of type safety by throwing a BeanNotOfRequiredTypeException if the bean is not of the required type. This means that ClassCastException can not be thrown on casting the result correctly, as can happen with getBean(String).
Spring Dependency Injection
=======================================
- The Spring container or the Object Factory has all the Dependencies one will need, You just have to outsource them and utilize them in your application.
- We just outsource the construction and injection of our object to an external entity i.e. Object Factory.
- In the above program when we retrieve the Coach Object, the coach object may have some additional dependencies, and these dependencies are just helper objects that it needs to perform the operation.
- So instead of manually build the coach object and all of its dependencies, Spring framework/factory does all the job for you.
Injection Types
=============================
- There are many tyoe of injection in Spring.
- Some are
Constructor Injection
Setter Injection
auto-wiring
Constructor Injection
===============================
- Dependencies will be added through constructor of the Dependency class/interface.
Development Process
================================
1. Define Dependency interface and class
2. Create a constructor in your class for injection
3. Configure the Dependency injection in Spring configuration file.
Do this in 1_Spring_Demo (Constructor Injection)
=========================================================
1. Create an interface FortuneService.java (Define Dependency interface and class)
package demo;
public interface FortuneService {
public String getfortune();
}
2. Create an implementation class HappyFortuneService.java
package demo;
public class HappyFortuneService implements FortuneService {
@Override
public String getfortune() {
return "Today is your Lucky Day";
}
}
3. In Coach.java interface add a method
package demo;
public interface Coach
{
public String getDailyWorkout();
public String getDailyFortune();
}
4. Implement those methods in all the implemented classes
5. In BadmintonCoach.java class (Create a constructor in your class for injection)
package demo;
public class BadmintonCoach implements Coach
{
//define a private field
private FortuneService fortuneService;
//define parameter constructor for dependency injection
public BadmintonCoach(FortuneService thefortuneService)
{
fortuneService = thefortuneService;
}
@Override
public String getDailyWorkout()
{
return "Spent 2 Hours on Badminton";
}
@Override
public String getDailyFortune() {
//Use my fortuneService to get a Fortune
return fortuneService.getfortune();
}
}
6. In XML file (Configure the Dependency injection in Spring configuration file)
7. In SpringTest.java call the method
// call the methods for fortune
System.out.println(theCoach.getDailyFortune());
8. run the SpringTest.java and See the output
NOTE:-
- Over here in the XML file what it does it, the Dependency section is actually doing this
HappyFortuneService fortune = new HappyFortuneService();
BadmintonCoach badminton = new BadmintonCoach(fortune);
- in the SpringTest.java the bean object theCoach, already has all the methods embeded to it.
- Only you have to change the class name in the configuration file and see the different output.
This is what happens
------------------------------------------
****
System.out.println(theCoach.getDailyFortune()); ---> public String getDailyFortune(); of Coach interface --> Goes to implementation in BadmintonCoach.java ---> goes to application.xml and the bean Dependency creates the object in the object Factory and points to the implementation class HappyFortuneService.java , Context Object in SpringTest already binds all the dependencies ---> from BadmintonCoach.java , return fortuneService.getFortune(); fortuneService is the object reference and getFortune() is the methood in interface ---> goes to implementation via context object --> return return "Today is your Lucky Day";
****
Setter Injection
===========================
- Spring will inject dependencies through Setter methood on your class
Development Process
-----------------------------
1. Create setter methods in your class for injection
2. Configure injection in Spring configuration file.
1_Spring_Demo (Setter Injection)
---------------------------------------------
1. Create a class CricketCoach.java and write this
package demo;
public class CricketCoach implements Coach {
private FortuneService fortuneService;
//Create a no-args constructor
public CricketCoach() {
System.out.println("CricketCoach : inside no-args constructor");
}
//Setter method
public void setFortuneService(FortuneService fortuneService) {
System.out.println("CricketCoach : inside setter method - setFortuneService");
this.fortuneService = fortuneService;
}
@Override
public String getDailyWorkout() {
return "Cricket Coach : Practice fast bowling and it is a great sport";
}
@Override
public String getDailyFortune() {
return fortuneService.getFortune();
}
}
2. In applicationContext.xml add this
3. Create a class SetterDemoApp.java and write this
package demo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SetterDemoApp
{
public static void main(String[] args)
{
// load the spring configuration file
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// retrieve bean from spring container
CricketCoach theCoach = context.getBean("myCricketCoach", CricketCoach.class);
// call methods on bean object
System.out.println(theCoach.getDailyWorkout());
System.out.println(theCoach.getDailyFortune());
// close the context
context.close();
}
}
***
NOTE : -
- In config file, the property name should be the name as the setter name without "set" word
e.g, setFortuneService(FortuneService fortuneService){ -->
}
----> this will be replacement of HappyFortuneService fortuneService = new HappyFortuneService();
---> this will create CricketCoach myCricketCoach = new CricketCoach();
---> this will create myCricketCoach.setFortuneService( fortuneService);
- SetterDemoApp will load and create the spring container and the objects will be created in Bean Factory
- getBean will get the objects and will call the respective methods
- First the Constructor will be called and then setter method will be executed in Bean/Object Factory then the methods that you want to call will be executed
***
Injecting Literal values
======================================
- Adding of some variables like string Literals ...etc
Development Process
=============================
1. Create setter methods in your class for Injection
2. Configure the Injection in Spring config file
Do this in 1_Spring_Demo
==================================
1. In CricketCoach.java create private fields and generate setters and getters
// Literal injection
// Add new private field and create setter methods
private String email;
private String team;
public void setEmail(String email) {
System.out.println("CricketCoach : Inside Setter method setEmail");
this.email = email;
}
public void setTeam(String team) {
System.out.println("CricketCoach : Inside setter method setTeam");
this.team = team;
}
public String getEmail() {
return email;
}
public String getTeam() {
return team;
}
2. In applicationContext.xml under bean id = myCricketCoach add this properties for setter injection
- This will set the property to the values that we have assigned.
3. In SetterDemoApp.java call those getter methods to check the output
// call methods to get Literal values
System.out.println(theCoach.getEmail());
System.out.println(theCoach.getTeam());
***
Note :-
- Through xml file first no args constructor will be called for object creation in bean/object factory
- then the setter methods will be called automatically to assign the values through objects
- All the objects will be embeded to context object in ClassPathXMLApplicationContext in SetterDemoApp
- The objects are retrieved as the getBean() is called with referencing the class in the xml file
- Now the methods are called using the object in SetterDemoApp class
***
Question
------------------
For the CricketCoach example with Setter Injection, why do we use the CricketCoach class instead of the Coach interface?
Answer
------------------
The getTeam() method is only defined in the CricketCoach class. It is not part of the Coach interface.
As a result, you would need the following code:
CricketCoach theCricketCoach = context.getBean("myCricketCoach", CricketCoach.class);
The Coach interface has two methods: getDailyWorkout and getDailyFortune
The CricketCoach class has four methods: getDailyWorkout, getDailyFortune, getTeam and setTeam
When you retrieve a bean from the Spring container using the Coach interface:
Coach theCricketCoach = context.getBean("myCricketCoach", Coach.class);
You only have access to the methods defined in the Coach interface: getDailyWorkout and getDailyFortune. Even though the actual implementation has additional methods, you only have visibility to methods that are defined at the Coach interface level.
When you retrieve a bean from the Spring container using the CricketCoach class:
CricketCoach theCricketCoach = context.getBean("myCricketCoach", CricketCoach.class);
You have access to the methods defined in the Coach interface: getDailyWorkout and getDailyFortune.
ALSO, you have access to the additional methods defined in the CricketCoach class: getTeam, setTeam.
The bottom line is it depends on how you retrieve the object and assign it ... that determines the visibility you have to the methods.
Injecting Values from Properties File
==================================================
- In above program the values were hardcoded into the config file of the application i.e. applicationContext.xml
- Here we can put everything into a external Properties file and read the values from it.
Development Process
============================
1. Create a properties File
2. Load Properties file into Spring Config File
3. Reference value from Properties file
1. Create a properties File
-------------------------------
sport.properties created and this was written
foo.email=debiprasadmishra50@gmail.com
foo.team=Chennai Super kings
format is name=value
***name can be anything
***If no value is there, default value is null
2. Load Properties file into Spring Config File
-------------------------------------------------------
- In applicationContext.xml load the properties file in first section or in first line [line (10)]
This will load the properties file into the config file/Bean factory
3. Reference value from Properties file
------------------------------------------------
- Under bean myCricketCoach inject properties like this
- Comment the literal injection part as the value should be assigned once through one type
i.e. either literal injection or through properties file
4. Run the SetterDemoApp.java and see the output
***
Note :-
- values should be written like this ${name in the properties file}
***
Spring Bean Scopes
=================================================
- Default scope of bean is singleton i.e, Spring container creates only one instance of bean by default
- It is in cached in memory
- All requests for bean will return a shared referenceto the same bean
- It is just like String literal, e.g.
Coach theCoach = context.getBean("myCoach", Coach.class)
Coach alphaCoach = context.getBean("myCoach", Coach.class)
- Here the bean will be created for theCoach and in the next the alphaCoach will just be a reference to the previously created bean. They will point to the same memory area.
Spring Scopes (5 scopes)
--------------------
- singleton -
we can explicitely declare the scope of a bean
1. singleton - Create a single shared instance of bean. It is the Default scope
2. prototype - Creates a new bean instance for each container request, it is like the new keyword
3. request - Scoped to HTTP web request, Only used for Web Apps
4. session - Scoped to HTTP web session, Only used for Web Apps
5. global-session - Scoped to global HTTP session. Only used for Web Apps
Do this
===================
1. Copy and paste 1_Spring_Demo to 2_Spring_Scope
2. Delete the properties file, all main() classes, all coach Classes except BadmintonCoach.java
3. Rename applicationContext to beanScope-applicationContext.xml and write this
4. Create a main() class BeanScopeDemoApp.java and write this
package demo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanScopeDemoApp
{
public static void main(String[] args)
{
// load the spring config file
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beanScope-applicationContext.xml");
// retrieve the spring container
Coach theCoach = context.getBean("myCoach", Coach.class);
Coach alphaCoach = context.getBean("myCoach", Coach.class);
// same hashcode, Point to same direction
System.out.println(theCoach);
System.out.println(alphaCoach);
System.out.println(System.identityHashCode(theCoach));
System.out.println(System.identityHashCode(alphaCoach));
boolean result = (theCoach == alphaCoach);
System.out.println(result);
}
}
5. Run BeanScopeDemoApp.java and see this
For scope=prototype the object will have different hashcode, i.e, they are different instances
and for scope = singleton, the objects will have same hashcode and they are same instances
Spring Bean LifeCycle
===================================
Spring Container Starts ---> Bean Instantiated ---> Dependencies Injected ---> Internal Spring Processing ---> [Your Custom Init method] ---> Bean is ready to Use ---> Methods are called using Bean Object ---> Container/Application shutdown ---> [Your custom Destroy method]
Init and Destroy method configuration
-----------------------------
Development Process
-------------------------------
1. Define your init and destroy methods in bean Class
2. Configure those methods in Spring Configuration File
init and destroy methods can have
-----------------------------------------
Access modifier
The method can have any access modifier (public, protected, private)
Return type
The method can have any return type. However, "void" is most commonly used. If you give a return type just note that you will not be able to capture the return value. As a result, "void" is commonly used.
Method name
The method can have any method name.
Arguments
The method can not accept any arguments. The method should be no-arg.
Do this
=====================
1. Copy and paste and rename 2_Spring_Scope to 3_Spring_LifeCycle
2. Rename the XML file to beanLifecycle-applicationContext.xml
3. Rename the main() app i.e. the BeanScopeDemoApp.java to BeanLifecycleDemoApp.java and change the file_name in the context object creation and write this
// load the spring config file
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beanLifecycle-applicationContext.xml");
// retrieve bean from spring container
Coach theCoach = context.getBean("myCoach", Coach.class);
System.out.println(theCoach.getDailyWorkout());
System.out.println(theCoach.getDailyFortune());
// close the context
context.close();
4. Add init and destroy method in BadmintonCoach.java
package demo;
public class BadmintonCoach implements Coach {
public BadmintonCoach() {
}
// define a private field
private FortuneService fortuneService;
// define parameter constructor for dependency injection
public BadmintonCoach(FortuneService thefortuneService) {
fortuneService = thefortuneService;
}
@Override
public String getDailyWorkout() {
return "Spent 2 Hours on Badminton";
}
@Override
public String getDailyFortune() {
// Use my fortuneService to get a Fortune
return "In BadmintonCoach : " + fortuneService.getFortune();
}
// add an init method
public void doMyStartupStuff()
{
System.out.println("BadmintonCoach : Inside init method : doMyStartupStuff");
}
// add an destroy method
public void doMyCleanupStuff()
{
System.out.println("BadmintonCoach : Inside destroy method : doMyCleanupStuff");
}
}
5. In xml file write this
6. run the BeanLifecycleDemoApp.java and see the output, first the init() will execute, then your custom methods, then the destroy method
***
Note :-
There is a subtle point you need to be aware of with "prototype" scoped beans. For "prototype" scoped beans, Spring does not call the destroy method.
In contrast to the other scopes, Spring does not manage the complete lifecycle of a prototype bean: the container instantiates, configures, and otherwise assembles a prototype object, and hands it to the client, with no further record of that prototype instance.
Thus, although initialization lifecycle callback methods are called on all objects regardless of scope, in the case of prototypes, configured destruction lifecycle callbacks are not called. The client code must clean up prototype-scoped objects and release expensive resources that the prototype bean(s) are holding.
***
*****
Important Application
To call destroy method on prototype scoped beans
=============================================================
1. Create a custom bean processor. This bean processor will keep track of prototype scoped beans. During shutdown it will call the destroy() method on the prototype scoped beans. The custom processor is configured in the spring config file.
2. The prototype scoped beans MUST implement the DisposableBean interface. This interface defines a "destory()" method.
public class TrackCoach implements Coach, DisposableBean {
...
// add a destroy method
@Override
public void destroy() throws Exception {
System.out.println("TrackCoach: inside method doMyCleanupStuffYoYo");
}
}
3. The spring configuration must be updated to use the destroy-method of "destroy".
4. In this app, BeanLifeCycleDemoApp.java is the main program. BadmintonCoach.java is the prototype scoped bean. BadmintonCoach implements the DisposableBean interface and provides the destroy() method. The custom bean processing is handled in the MyCustomBeanProcessor class.
Programs
--------------------
1. Coach.java
----------------
package demo;
public interface Coach {
public String getDailyWorkout();
public String getDailyFortune();
}
2. BadmintonCoach.java
-------------------------------
package demo;
import org.springframework.beans.factory.DisposableBean;
public class BadmintonCoach implements Coach, DisposableBean {
private FortuneService fortuneService;
public BadmintonCoach() {
}
public BadmintonCoach(FortuneService fortuneService) {
this.fortuneService = fortuneService;
}
@Override
public String getDailyWorkout() {
return "Spend 2 hours on Badminton";
}
@Override
public String getDailyFortune() {
return "Just Do It: " + fortuneService.getFortune();
}
// add an init method
public void doMyStartupStuff() {
System.out.println("BadmintonCoach: inside method doMyStartupStuff");
}
// add a destroy method
@Override
public void destroy() throws Exception {
System.out.println("BadmintonCoach: inside method doMyCleanupStuff");
}
}
3. FortuneService.java
-------------------------------
package demo;
public interface FortuneService {
public String getFortune();
}
4. HappyFortuneService.java
package demo;
public class HappyFortuneService implements FortuneService {
@Override
public String getFortune() {
return "Today is your lucky day!";
}
}
5. BeanLifeCycleDemoApp.java
-------------------------------
package demo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanLifeCycleDemoApp {
public static void main(String[] args) {
// load the spring configuration file
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("beanLifeCycle-applicationContext.xml");
// retrieve bean from spring container
Coach theCoach = context.getBean("myCoach", Coach.class);
System.out.println(theCoach.getDailyWorkout());
System.out.println(theCoach.getDailyFortune());
// close the context
context.close();
}
}
6. MyCustomBeanProcessor.java
------------------------------------
package demo;
import java.util.LinkedList;
import java.util.List;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyCustomBeanProcessor implements BeanPostProcessor, BeanFactoryAware, DisposableBean {
private BeanFactory beanFactory;
private final List