Spring Framework
“Most popular application development framework for enterprise Java.”
Make J2EE easier to use
Make the common tasks easier
Promote good programming practice
You can focus on the domain problems
An open source application framework
Lightweight solution for enterprise applications
Extensible for other frameworks
De facto standard of Java Enterprise Application
provide the fundamental parts of the framework, including IoC and Dependency Injection features Context
it is a means to access objects in a framework-style manner that is similar to a JNDI Registry
provides a powerful expression language for querying and manipulating an object graph at runtime
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.
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.
The Web layer consists of the spring-web, spring-webmvc, spring-websocket, and spring-webmvc-portlet modules.
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 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
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
<?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>
<?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>
<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>
InputStream is = new FileInputStream("beans.xml");
BeanFactory factory = new XmlBeanFactory(is);
HelloWorld obj = (HelloWorld) factory.getBean("helloWorld");
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});
ApplicationContext context = new FileSystemXmlApplicationContext("c:/foo.xml");
ApplicationContext context = new AnnotationConfigApplicationContext(UserConfig.class);
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();
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.
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'
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; }
}
“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.”
Pass dependencies in via constructor
<constructor-arg value="Joe Doe"/>
equals
GreetingServiceImpl greetingService = new GreetingServiceImpl(“Joe Doe”);
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" />
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.
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"
<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.
<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
Pass dependencies in via property setters
equals
GreetingServiceImpl greetingService = new GreetingServiceImpl();
greetingService.setGreeting("Hello");
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"/>
xml-service-config.xml
xml-repository-config.xml
xml-context-config.xml
<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.
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
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;
}
// ...
}
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Resource(name="myMovieFinder")
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}
@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
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"/>
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 {
// ...
}
Scope | Description |
---|---|
singleton | This scopes the bean definition to a single instance per Spring IoC container (default). |
prototype | This scopes a single bean definition to have any number of object instances. |
request | This scopes a bean definition to an HTTP request. Only valid in the context of a web-aware Spring ApplicationContext. |
session | This scopes a bean definition to an HTTP session. Only valid in the context of a web-aware Spring ApplicationContext. |
global-session | This scopes a bean definition to a global HTTP session. Only valid in the context of a web-aware Spring ApplicationContext. |
“ 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. ”