You are on page 1of 24

Spring Core Framework

Tutorial
Application Context

Why we require Spring Framework?


Spring provides multiple features: We can use Spring with Web,
for Dependency Injection : Whatever dependency we need we can ask someone else to give those
dependencies. So, in future if we change our dependency we don’t need to change our code.

See program Maven_02_Demo.

 Select Maven Project


 Click Next
 Check Use default Workspace location then Click next
 Select maven-archetype-quickstart for simple POJO application or maven-archetype-webapp for WEB
application
 Click next
 Mention Group Id : com.hussain, Artifact Id: as Project Name(Maven_02_Demo) and set Package with
all small letters then Click Finish.
Spring Core Framework
See program Maven_03_SpringCoreFramwork.

Add the following dependency in pom.xml for spring version 5

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>

Vehicle.java
package com.hussain.Maven_03_SpringCoreFramwork;
public interface Vehicle {
void drive();
}

Car.java
package com.hussain.Maven_03_SpringCoreFramwork;
public class Car implements Vehicle{
public void drive() {
System.out.println("Car chal raha hai");
}
}
Bike.java
package com.hussain.Maven_03_SpringCoreFramwork;
public class Bike implements Vehicle{
public void drive() {
System.out.println("Bike bhaag raha hai.");
}
}

spring.xml
<?xml version="1.0" encoding="UTF-8"?>

<!-- since xml always goes for user defined tags(custom tags)
and these custom tags need a definition. so, beans is to be defined as
follows -->

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

<!-- bean id="vehicle"


class="com.hussain.Maven_03_SpringCoreFramwork.Car"/-->
<bean id="vehicle" class="com.hussain.Maven_03_SpringCoreFramwork."/>

</beans>

Note: beans configuration can be taken with the help of Google. Here we are
using the spring 5 xml configuration
AppTest.java(Main file)
package com.hussain.Maven_03_SpringCoreFramwork;

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

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

public class AppTest{


public static void main(String [] args){
ApplicationContext context=new
ClassPathXmlApplicationContext("spring.xml");
Vehicle obj=(Vehicle) context.getBean("vehicle");
/*
* here it is not clear that which class instance it to be generated
whether of Car or of Bike
* for this we will create an xml file spring.xml(any name) and we
will define in bean tag
* and mention the xml file in ClassPathXmlApplicationContext() as
argument to load all configuration.
*/
obj.drive();//Car chal raha hai

/*
* Now we are done.
* We are not creating any object of Car but Spring has provided us
the object of car.
*
* if we change below
* <bean id="vehicle"
class="com.hussain.Maven_03_SpringCoreFramwork.Car"/>
* to
* <bean id="vehicle"
class="com.hussain.Maven_03_SpringCoreFramwork.Bike"/>
* in spring.xml then it will give the object of Bike
*/

/*
* below is just a simple test that while execution if we change Car
to Bike or vice versa in spring.xml
* we don't need to recompile it. It will be reflected itself. So,
no need to change the source code of java here.
* So, testing becomes easy and cheap.
*/
int i=0;
while(i++<20){
context=new ClassPathXmlApplicationContext("spring.xml");
obj=(Vehicle) context.getBean("vehicle");
obj.drive();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}
}
Annotation Based Configuration

Below is the project structure:

Vehicle.java
package com.hussain.maven_04_annotation;
public interface Vehicle {
void drive();
}

Car.java
package com.hussain.maven_04_annotation;
import org.springframework.stereotype.Component;
@Component
public class Car implements Vehicle{
public void drive(){
System.out.println("Chal Raha Hai.");
}
}

Bike.java
package com.hussain.maven_04_annotation;
import org.springframework.stereotype.Component;
@Component
public class Bike implements Vehicle{
public void drive(){
System.out.println("Bhaag Raha Hai.");
}
}
spring.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

<context:component-scan base-
package="com.hussain.maven_04_annotation"></context:component-scan>

</beans>

App.java
package com.hussain.maven_04_annotation;

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

public class App


{
public static void main( String[] args ){
ApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
Vehicle obj=(Vehicle) context.getBean("bike");
obj.drive();
obj=(Vehicle) context.getBean("car");
obj.drive();
}
}
Bean Property – Setter Injection
Bean properties can be set using xml based configuration or annotation based configuration. Below is
the demo using xml property. For this, setters and getters (Setter Injection) and default Constructor are
required.

Below is the Project Structure:

Tyre.java
package com.hussain.maven_05_beanproperty;
public class Tyre {
private String brand;

public String getBrand() {


return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}

public String toString(){


return "Tyre[brand="+brand+"]";
}
}

spring.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

<bean id="tyre" class="com.hussain.maven_05_beanproperty.Tyre">


<property name="brand" value="MRF"></property>
<!-- if property is not set then the property will have default
value-->
</bean>

</beans>

App.java
package com.hussain.maven_05_beanproperty;

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

public class App


{
public static void main( String[] args ){
ApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
Tyre tyre=(Tyre)context.getBean("tyre");
System.out.println(tyre);
}
}

Bean Property – Constructor Injection


For Constructor Injection just write the Constructor (to initialize
properties) of Tyre Class and modify spring.xml with the following:

<bean id="tyre" class="com.hussain.maven_05_beanproperty.Tyre">


<!-- for Setter Injection use below tag -->
<!-- property name="brand"><value>CEAT</value></property-->
<!-- for Constructor Injection use below tag -->
<constructor-arg value="MRF" type="String"></constructor-arg>
</bean>
Autowired Annotation
This is specially used when a class has reference data member which needs to
be initialized using another class.
Here, what we are taking example is a class Car has a reference data member
Tyre tyre. So, tyre needs to be initialized using its class Tyre. Here, we
can use @Autowired.

Below is the project structure:

Vehicle.java
package com.hussain.maven_06_autowiredannotation;
public interface Vehicle {
void drive();
}

Tyre.java
package com.hussain.maven_06_autowiredannotation;
public class Tyre {
private String brand;
public Tyre(){ }
public Tyre(String brand) {
this.brand = brand;
}
//Setters and Getters
public String toString(){
return "Tyre[brand="+brand+"]";
}
}
Car.java
package com.hussain.maven_06_autowiredannotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Car implements Vehicle{

@Autowired
private Tyre tyre;

public Tyre getTyre() {


return tyre;
}

public void setTyre(Tyre tyre) {


this.tyre = tyre;
}

public void drive(){


System.out.println("Car...."+tyre);
}
}

spring.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

<!-- Below tag(Annotation based configuration) is used for Class Car -->
<context:component-scan base-package =
"com.hussain.maven_06_autowiredannotation"></context:component-scan>

<!-- below bean tag indicates xml based configuration for Tyre.
@Component annotation is to be written before Tyre then below bean
tag is not required. above context tag will suffice
-->
<bean id="tyre" class="com.hussain.maven_06_autowiredannotation.Tyre">
<property name="brand"><value>CEAT</value></property>
</bean>
</beans>

App.java
package com.hussain.maven_06_autowiredannotation;

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

public class App


{
public static void main( String[] args ){
ApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
Car obj=(Car) context.getBean("car");
obj.drive();
}
}
Configuration Bean
Annotation Based

For fully annotation based bean configuration we require an additional class


(we are writing AppConfig.java) with @Configuration to define configuration.
Now the class AppConfig is responsible to give objects.

Note: In this, no xml based configuration is required. Annotation based was introduce in version 2.5

Below is the project structure:

Samsung.java
package com.hussain.maven_07_configurationbean;

import org.springframework.stereotype.Component;

public class Samsung {

public void config(){


System.out.println("Octa core, 4gb ram, 12Mp Camera");
}

}
AppConfig.java
package com.hussain.maven_07_configurationbean;

import org.springframework.context.annotation.*;

@Configuration
public class AppConfig {

@Bean
public Samsung getPhone(){
return new Samsung();
}
}

App.java
package com.hussain.maven_07_configurationbean;

import org.springframework.context.ApplicationContext;
import
org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App{

public static void main( String[] args ){


ApplicationContext factory=new
AnnotationConfigApplicationContext(AppConfig.class);
Samsung s7=(Samsung) factory.getBean(Samsung.class);
S7.config();
}
}
Example 2: Here, we are taking two classes Samsung and Snapdragon. Snapdragon is implementing
MobileProcessor. AppConfig.java is responsible to give their objects. Samsung class has a reference
data member MobileProcessor cpu;

Below is the project structure:

MobileProcessor.java
package com.hussain.maven_08_configurationbean02;

public interface MobileProcessor {


void process();
}

Snapdragon.java
package com.hussain.maven_08_configurationbean02;

import org.springframework.stereotype.Component;

public class Snapdragon implements MobileProcessor {

public void process() {


System.out.println("World's best CPU");
}
}
Samsung.java
package com.hussain.maven_08_configurationbean02;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

public class Samsung {

@Autowired
MobileProcessor cpu;

public MobileProcessor getCpu() {


return cpu;
}

public void setCpu(MobileProcessor cpu) {


this.cpu = cpu;
}

public void config(){


System.out.println("Octa core, 4gb ram, 12Mp Camera");
cpu.process();
}

AppConfig.java
package com.hussain.maven_08_configurationbean02;
import org.springframework.context.annotation.*;

@Configuration
public class AppConfig {

@Bean
public Samsung getPhone(){
return new Samsung();
}

@Bean
public MobileProcessor getProcessor(){
return new Snapdragon();
}
}
App.java
package com.hussain.maven_08_configurationbean02;

import org.springframework.context.ApplicationContext;
import
org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App{

public static void main( String[] args ){


ApplicationContext factory=new
AnnotationConfigApplicationContext(AppConfig.class);
Samsung s7=(Samsung) factory.getBean(Samsung.class);
s7.config();
}
}
Configuration Bean
Annotation Component
Autowired Primary Qualifier

In the last two examples, we were defined functions to generate objects in AppConfig.java.
Now, we don’t want to write them. Then, what we need to do is write @Component before Samsung
and Sanpdragon and add one more annotation
@ComponentScan(basePackages="com.hussain.maven_09_configurationbean03"). This
is actually an alternate way of the following configuration in spring.xml

<context:component-scan base-
package="com.hussain.maven_06_autowiredannotation"></context:component-scan>

So, below is the project structure:

MobileProcessor.java
package com.hussain.maven_09_configurationbean03;
public interface MobileProcessor {
void process();
}
Snapdragon.java
package com.hussain.maven_09_configurationbean03;

import org.springframework.stereotype.Component;

@Component
public class Snapdragon implements MobileProcessor {

public void process() {


System.out.println("World's best CPU");
}
}

Samsung.java
package com.hussain.maven_09_configurationbean03;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

//@Component("samsung") //default name =>non qualified and de-capitalized


@Component
public class Samsung {

@Autowired
MobileProcessor cpu;

public MobileProcessor getCpu() {


return cpu;
}

public void setCpu(MobileProcessor cpu) {


this.cpu = cpu;
}

public void config(){


System.out.println("Octa core, 4gb ram, 12Mp Camera");
cpu.process();
}

}
AppConfig.java
package com.hussain.maven_09_configurationbean03;

import org.springframework.context.annotation.*;

@Configuration
@ComponentScan(basePackages="com.hussain.maven_09_configurationbean03")
public class AppConfig {

App.java
package com.hussain.maven_09_configurationbean03;

import org.springframework.context.ApplicationContext;
import
org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App{

public static void main( String[] args ){


ApplicationContext factory=new
AnnotationConfigApplicationContext(AppConfig.class);
Samsung s7=(Samsung) factory.getBean(Samsung.class);
s7.config();
}
}

In the last example, if we take one more class MediaTec.java(with @Component) implementing
MobileProcessor.java. So, we have now two classes Snapdragon and MediaTek implementing
MobileProcessor and Samsung needs MobileProcessor reference. So, in this case the compiler will get
confused which instance is to given to Samsung as MobileProcessor reference as there are two beans
Snapdragon and MediaTek that are giving MobileProcessor.
In order to avoid this, we can use @Primary before any of the beans Snapdragon and MediaTek or
@Qualifier("snapdragon") can be used just before the reference data member. If both are used
then @Qualifier("snapdragon") will be considered.
Below is the project structure:

MobileProcessor.java
package com.hussain.maven_09_configurationbean03;

public interface MobileProcessor {


void process();
}

Snapdragon.java
package com.hussain.maven_09_configurationbean03;

import org.springframework.stereotype.Component;

@Component
public class Snapdragon implements MobileProcessor {

public void process() {


System.out.println("World's best CPU");
}
}
MediaTek.java
package com.hussain.maven_09_configurationbean03;

import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

@Component
@Primary
public class MediaTek implements MobileProcessor {

public void process() {


System.out.println("2nd best cpu");
}
}

Samsung.java
package com.hussain.maven_09_configurationbean03;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

//@Component("samsung") //default name =>non qualified and de-capitalized


@Component
public class Samsung {

@Autowired
@Qualifier("snapdragon")
MobileProcessor cpu;

public MobileProcessor getCpu() {


return cpu;
}

public void setCpu(MobileProcessor cpu) {


this.cpu = cpu;
}

public void config(){


System.out.println("Octa core, 4gb ram, 12Mp Camera");
cpu.process();
}

}
AppConfig.java
package com.hussain.maven_09_configurationbean03;

import org.springframework.context.annotation.*;

@Configuration
@ComponentScan(basePackages="com.hussain.maven_09_configurationbean03")
public class AppConfig {

App.java
package com.hussain.maven_09_configurationbean03;

import org.springframework.context.ApplicationContext;
import
org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App{

public static void main( String[] args ){


ApplicationContext factory=new
AnnotationConfigApplicationContext(AppConfig.class);
Samsung s7=(Samsung) factory.getBean(Samsung.class);
s7.config();
}
}

You might also like