Spring Framework

What’s Spring

“Most popular application development framework for enterprise Java.”

History

History (cont)

  • 2011 - Spring 3.1
    • Cache abstraction
    • Bean definition profiles
  • 2011 - Spring 3.2
  • 2015 - Spring 4.x
    • Improvements in Spring 4.X include support for Java SE 8
    • Groovy 2, and a few aspects of Java EE7.

Goals

Make J2EE easier to use

Make the common tasks easier

Promote good programming practice

You can focus on the domain problems

What is Spring today?

An open source application framework

Lightweight solution for enterprise applications

Extensible for other frameworks

De facto standard of Java Enterprise Application

Spring Modules

Spring Modules

Core Container

Core and Beans

provide the fundamental parts of the framework, including IoC and Dependency Injection features Context

Context

it is a means to access objects in a framework-style manner that is similar to a JNDI Registry

Expression language

provides a powerful expression language for querying and manipulating an object graph at runtime

AOP

The spring-aop module provides an AOP Alliance-compliant aspect-oriented programming implementation allowing you to define,

for example, method interceptors and pointcuts to cleanly decouple code that implements functionality that should be separated.

Instrumentation

The spring-instrument module provides class instrumentation support and classloader implementations to be used in certain application servers.

The spring-instrument-tomcat module contains Spring’s instrumentation agent for Tomcat.

Data Access/Integration

  • JDBC - provides a JDBC-abstraction layer
  • ORM - provides integration layers for popular object-relational mapping APIs, including JPA, JDO, Hibernate and iBatis
  • OXM - provides an abstraction layer that supports Object/XML mapping implementations for JAXB, Castor, XMLBeans, JiBX and XStream.
  • JMS – contains features for producing and consuming messages.
  • Transaction - supports programmatic and declarative transaction management

Test

  • The spring-test module supports the unit testing and integration testing of Spring components with JUnit or TestNG.
  • It provides consistent loading of Spring ApplicationContexts and caching of those contexts
  • It also provides mock objects that you can use to test your code in isolation

Web Layer

The Web layer consists of the spring-web, spring-webmvc, spring-websocket, and spring-webmvc-portlet modules.

Full-fledged Spring web application

overview-full

Inversion Of Control

What is IoC?

  • is a concept in application development
  • "don’t call me, I’ll call you“
  • one form is Dependency Injection (DI)

Spring IoC Container

Spring IoC Container

Spring IoC Container

The container gets its instructions on what objects to instantiate, configure,and assemble by reading configuration metadata provided.

The configuration metadata can be represented either by XML, Java annotations, Java-base configuration

Spring Container

Spring Container

Spring Container

Spring provides the following two interfaces that act as containers. The org.springframework.beans and org.springframework.context packages are the basis for Spring Framework’s IoC container

  • BeanFactory: This is a basic container, and all other containers implement BeanFactory
  • ApplicationContext: This refers to the subinterface of BeanFactory and is mostly used as a container in enterprise applications

Bean Factory

What is Bean Factory

Spring Bean Factory

Application Context

ApplicationContext is also used to represent Spring Container, built upon the BeanFactory interface. ApplicationContext is suitable for Java EE applications, and it is always preferred over BeanFactory. All functionality of BeanFactory is included in ApplicationContext

Application Context

WebApplication Context

Configuration Application Context

Basic Configuration Overview

Simple Spring XML Configuration

<?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">

</beans>

Basic Configuration Overview

Spring XML Configuration with Annotation Support

<?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.assanai.annotation" />

</beans>

XML-based configuration metadata


<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.assanai.annotation" />

    
        
    

    
        
    
    
</beans>
                    

Working with BeanFactory


InputStream is = new FileInputStream("beans.xml");
BeanFactory factory = new XmlBeanFactory(is);
HelloWorld obj = (HelloWorld) factory.getBean("helloWorld");
                     

Working with Application Context

Instantiating a container


ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});

ApplicationContext context = new FileSystemXmlApplicationContext("c:/foo.xml");

ApplicationContext context = new AnnotationConfigApplicationContext(UserConfig.class);

                    

Using the container

With an application context in hand, you can retrieve beans from the Spring container by calling the context’s getBean() method.


// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});

// retrieve configured instance
PetStoreService service = context.getBean("petStore", PetStoreService.class);

// use configured instance
List<String> userList = service.getUsernameList();
                    

Spring-Manage Beans

What is Bean?

Bean overview

A Spring IoC container manages one or more beans. These beans are created with the configuration metadata that you supply to the container, for example, in the form of XML <bean/> definitions.





    



    





                

Bean Naming Conventions

The convention is to use the standard Java convention for instance field names when naming beans. That is, bean names start with a lowercase letter, and are camel-cased.

'accountManager', 'accountService', 'userDao', 'loginController'

What is a bean definition?

Defines a bean for Spring to manage

  • class (required): fully qualified java class name
  • id: the unique identifier for this bean
  • configuration: (singleton, init-method, etc.)
  • constructor-arg: arguments to pass to the constructor at creation time
  • property: arguments to pass to the bean setters at creation time
  • Collaborators: other beans needed in this bean (a.k.a dependencies), specified in property or constructor-arg

Sample bean definition




    
        
    

    
        
    

    
        1
    


                    

public class ExampleBean {
    private AnotherBean beanOne;
    private YetAnotherBean beanTwo;
    private int i;

    public void setBeanOne(AnotherBean beanOne) { this.beanOne = beanOne; }
    public void setBeanTwo(YetAnotherBean beanTwo) { this.beanTwo = beanTwo; }
    public void setIntegerProperty(int i) { this.i = i; }
}
                    

Dependency Injection

“An injection is the passing of a dependency (a service) to a dependent object (a client). Passing the service to the client, rather than allowing a client to build or find the service, is the fundamental requirement of the pattern.”

Dependency Injection in Spring

Dependency Injection in Spring

  • Constructor Injection
    • By invoking a constructor containing a number of arguments, constructor-based DI can be accomplished. These arguments are injected at the time of instance instantiation.
  • Setter Injection
    • Setter-based DI is attained by calling setter methods on your beans. Using setter methods defined in a Spring configuration file, the dependencies are "set" in the objects.

Dependency Injection in Spring

Constructor Injection

Pass dependencies in via constructor

                           

   <constructor-arg value="Joe Doe"/>

                            

equals

 
GreetingServiceImpl greetingService = new GreetingServiceImpl(“Joe Doe”);
                         

Example Constructor-Injection

 
public class SimpleMovieLister {
    // the SimpleMovieLister has a dependency on a MovieFinder
    private MovieFinder movieFinder;
    // a constructor so that the Spring container can inject a MovieFinder
    public SimpleMovieLister(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
    // business logic that actually uses the injected MovieFinder is omitted...
}
                        
 

    <constructor-arg ref="movieFinder"/>


<bean id="movieFinder" class="example.hello.MovieFinder" />

                    

Constructor argument resolution

 
package x.y;
public class Foo {

     public Foo(Bar bar, Baz baz) {
        // ...
     }

 }
                             
 

<bean id="foo" class="x.y.Foo">
    <constructor-arg ref="bar"/>
    <constructor-arg ref="baz"/>
</bean>

<bean id="bar" class="x.y.Bar"/>

<bean id="baz" class="x.y.Baz"/>

                         

No potential ambiguity exists, assuming that Bar and Baz classes are not related by inheritance. Thus the following configuration works fine, and you do not need to specify the constructor argument indexes and/or types explicitly in the <constructor-arg> element.

Resolving ambiguity

 
public Employee(String employeeName, int employeeAge, boolean married) {
    this.employeeName = employeeName;
    this.employeeAge = employeeAge;
    this.married = married;
}
                         
 

    <constructor-arg value="Assani Manurat" />
    <constructor-arg value="False" />
    <constructor-arg value="28" />

                         

If the orders in which constructor-arg is deined are not matching, then you will get the following error:

 
Exception in thread "main" org.springframework.beans.factory.
UnsatisfiedDependencyException: Error creating bean with name employee defined in the classpath
resource [beans.xml]: Unsatisfied dependency expressed through
constructor argument with index 1 of type [int]: Could not convert
constructor argument value of type [java.lang.String] to required
type [int]: Failed to convert value of type 'java.lang.String' to
required type 'int'; nested exception is java.lang.NumberFormatException: For input string: "False"
                        

Solution – use index attribute

 

    <constructor-arg value="Assani Manurat" index="0"/>
    <constructor-arg value="False" index="2" />
    <constructor-arg value="28" index="1" />

                         

Remember that the index attribute always starts with 0.

Solution – use type attribute

 

    <constructor-arg value="Assanai Manurat" type="java.lang.String"/>
    <constructor-arg value="False" type="java.lang.Boolean" />
    <constructor-arg value="28" type="java.lang.Integer" />

                         

The solution to this problem is to use the type attribute to specify the exact data type for the constructor

Setter Injection

Pass dependencies in via property setters

						

    

                        
					

equals

						
GreetingServiceImpl greetingService = new GreetingServiceImpl();
greetingService.setGreeting("Hello");
                        
					

Setter Injection (2)

						
public class ExampleBean {
    private AnotherBean beanOne;
    private YetAnotherBean beanTwo;
    private int integerProperty;
    public void setBeanOne(AnotherBean beanOne) {
        this.beanOne = beanOne;
    }
    public void setBeanTwo(YetAnotherBean beanTwo) {
        this.beanTwo = beanTwo;
    }
    public void setIntegerProperty(int integerProperty) {
        this.integerProperty = integerProperty;
    }
}
                    
						
<bean id="exampleBean" class="examples.ExampleBean">
    
    <property name="beanOne">
        <ref bean="anotherExampleBean"/>
    </property>
    <!-- setter injection using the neater ref attribute -->
    <property name="beanTwo" ref="yetAnotherBean"/>
    <property name="integerProperty" value="1"/>
</bean>
<bean id="anotherExampleBean" class="examples.AnotherBean"/>
<bean id="yetAnotherBean" class="examples.YetAnotherBean"/>
                    

Try...

Additional Features

  • Importing configuration files
  • Autowing

Importing configuration files

xml-service-config.xml

                            

    

                        

xml-repository-config.xml

                            

                        

xml-context-config.xml

                            


                        

Autowiring

  • Advantages
    • can significantly reduce the need to specify properties or constructor arguments
    • can update a configuration as your objects evolve
  • Disadvantages
    • cannot autowire simple properties (primitives)

Autowiring modes

  • No
    • (Default) No autowiring. Bean references must be defined via a ref element
  • byName
    • Autowiring by property name. Spring looks for a bean with the same name as the property that needs to be autowired
  • byType
    • Allows a property to be autowired if exactly one bean of the property type exists in the container. If more than one exists, a fatal exception is thrown, which indicates that you may not use byType autowiring for that bean

Autowiring modes

  • constructor
    • this is similar to autowire byType, but here the constructor is used to inject a dependency

Stereotype

stereotype

Basic configuration

                        


    <context:annotation-config />
    <context:component-scan base-package="org.example"/>
    


                            

<context:annotation-config/> is configured, you can start annotating your code to indicate that Spring should automatically wire values into properties, methods, and constructors.

@Autowired

                        
public class SimpleMovieLister {

    private MovieFinder movieFinder;

    @Autowired
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    // ...

}
                        

As expected, you can apply the @Autowired annotation to "traditional" setter methods

@Autowired

You can apply @Autowired to constructors and fields

                        
public class MovieRecommender {

    @Autowired
    private MovieCatalog movieCatalog;

    private CustomerPreferenceDao customerPreferenceDao;

    @Autowired
    public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
        this.customerPreferenceDao = customerPreferenceDao;
    }

    // ...

}
                        

@Resource

  • Spring also supports injection using the JSR-250 @Resource annotation on fields or bean property setter methods.
  • This is a common pattern in Java EE 5 and 6, for example in JSF 1.2 managed beans or JAX-WS 2.0 endpoints.
  • Spring supports this pattern for Spring-managed objects as well
                        
public class SimpleMovieLister {

    private MovieFinder movieFinder;

    @Resource(name="myMovieFinder")
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

}
                        

Detecting classes and Registering bean definitions

                        
@Service
public class SimpleMovieLister {

    private MovieFinder movieFinder;

    @Autowired
    public SimpleMovieLister(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

}
                        
                        
@Repository
public class JpaMovieFinder implements MovieFinder {
    // implementation elided for clarity
}
                        

Spring can automatically detect stereotyped classes and register corresponding BeanDefinitions with the ApplicationContext

Detecting classes and Registering bean definitions

To autodetect these classes and register the corresponding beans, you need to add @ComponentScan to your @Configuration class

                        
@Configuration
@ComponentScan(basePackages = "org.example")
public class AppConfig  {
    ...
}
                        

alternative using XML

                        


    <context:component-scan base-package="org.example"/>


                        

Providing a scope for autodetected components

Default and most common scope for autodetected components is singleton

Sometimes you need other scopes, which Spring 2.5 provides with a new @Scope annotation

                        
@Scope("prototype")
@Repository
public class MovieFinderImpl implements MovieFinder {
    // ...
}
                        

Try...

Spring Bean Scopes

ScopeDescription
singletonThis scopes the bean definition to a single instance per Spring IoC container (default).
prototypeThis scopes a single bean definition to have any number of object instances.
requestThis scopes a bean definition to an HTTP request. Only valid in the context of a web-aware Spring ApplicationContext.
sessionThis scopes a bean definition to an HTTP session. Only valid in the context of a web-aware Spring ApplicationContext.
global-sessionThis scopes a bean definition to a global HTTP session. Only valid in the context of a web-aware Spring ApplicationContext.

Singleton

Singleton



    

                

Prototype

Prototype



    

                

Request, session, global session

“ The request, session, and global session scopes are only available if you use a web-aware Spring ApplicationContext implementation (such as XmlWebApplicationContext).
If you use these scopes with regular Spring IoC containers such as the ClassPathXmlApplicationContext, you get an IllegalStateException complaining about an unknown bean scope. ”

Question?