spring1

emptyslowInternet and Web Development

Nov 12, 2013 (3 years and 4 months ago)

74 views

Text

Text

Text

Text

Text

Text

Text

Text

Text

Text

Text

Text

16 de mayo de 2009

Spring Framework


Part I. Dependency Injection



Buenos Aires, May 2009.

16 de mayo de 2009

Contents


The problem


The Spring Framework


Dependency Injection


DI Best Practices




16 de mayo de 2009

Contents

The problem


The Spring Framework


Dependency Injection


DI Best Practices




16 de mayo de 2009

Working with dependencies

public class DataProcessor {


public void processData() {



DataSource source = new DataSource();



List<Data> dataList = source.getDataList();



for(Data data : dataList) {




System.out.println(data);



}


}

}

-

DataProcessor gets the data from a class DataSource. DataProcessor process the data (print it out).
The DataProcessor is the client for the DataSource service.

-

DataSource gets the data from a source, for example an XML file.

-
Data has only one String property: “info”.

-
Important
: is the class DataSource, and how we connect the dependency between the DataProcessor
and a particular DataSource.

+
processData
()
DataProcessor
+
getDataList
()
DataSource
+
getInfo
()
+
setInfo
()
-
info
:
String
Data
16 de mayo de 2009

Working with dependencies


What happends if now I wish to change the data source, from an XML file to a
database or a web service?


What could be changed in the design to avoid coupling between
DataProcessor and DataSource? If I change the data source, I have to modify
the method processData also…

public class DataProcessor {


public void processData() {



DbDataSource source = new DbDataSource();



List<Data> dataList = source.getDataList();



for(Data data : dataList) {




System.out.println(data);



}


}

}

16 de mayo de 2009

Refactor to interface

public class DataProcessor {


private DataSource source;



public DataProcessor() {


source = new DataSourceDbImpl();

}



public void processData() {



List<Data> dataList = source.getDataList();

for(Data data : dataList) {


System.out.println(data);

}


}

}

+
processData
()
DataProcessor
+
getDataList
()
DataSourceDbImpl
+
getDataList
()
«interfaz»
DataSource
+
getDataList
()
DataSourceXmlImpl
+
getDataList
()
DataSourceWSImpl
+
getInfo
()
+
setInfo
()
-
info
:
String
Data
<<
creates
>>
public interface DataSource {



List<Data> getDataList();


}

16 de mayo de 2009

Refactor to interface


Using an interface is enough to avoid coupling?


Now DataProcessor has a dependence on the interface DataSource
and the implementation DataSourceDbImpl. DataProcessor
uses

the
interface, and has to
create

the implementation class.


Again, the design is very coupled.


Better would be if it has
only
dependence on the interface.


The problem is
: how, when, and where should we create the instances
of an object
dependences
?

16 de mayo de 2009


Passing the DataSource service implementation as a constructor parameter to the
DataProcessor. Changing this client:







To this one:








But we have now the dependece in the client… It’s a new problem.

Solution 1


Using a Constructor

public class Client3 {


public static void main(String[] args) {



DataSource source = new DataSourceDbImpl();



DataProcessor processor = new DataProcessor(source);



processor.processData();


}


}

public class Client1 {


public static void main(String[] args) {



DataProcessor processor = new DataProcessor();



processor.processData();


}

}

16 de mayo de 2009


Create an abstract factory to build the data sources. We can create an interface
DataProcessorFactory with many implementations, depending on the DataSource to be
used.


If we want a database data source, the new client should be changed to this:








But now we need many concrete factories, one per each dependence combination.


And also now is a new dependence between the client and the concrete factory.. The
dependency problem is now again in the client.

Solution 2


Abstract Factory Patter

public class Client4 {


public static void main(String[] args) {



DataProcessorFactory factory = new DataProcessorFactoryDbImpl();



DataSource source = factory.createDataSource();



DataProcessor processor = new DataProcessor(source);



processor.processData();


}

}

16 de mayo de 2009


We will have the same problem with the service locator pattern.


We pass a parameter in the constructor, indicanting the concrete data service.









The DataProcessor uses a service locator to find the concrete instance and set the data
source:


source = ServiceLocator.getDataSource(dataSource);


Now we have a dependece with the ServiceLocator class in each class that have
dependences.


Also we have “harcoded” the kind of data source we want in the client, the client is
coupled with the data source.

Solution 3


Service Locator Pattern

public class Client5 {


public static void main(String[] args) {



DataProcessor processor = new DataProcessor(ServiceLocator.DB);



processor.processData();


}

}


16 de mayo de 2009

Solution 4


Plugin Pattern


It’s there a way to depend only on the interfaces, and indicate the implementations in
runtime?


Plugin Pattern:
“Links classes during configuration rather than compilation

.
(PEAA).


This with reduce the coupling, and help testability, reusability, and flexibility.


How could we assemble the different objects in an application?


We should “inject” the dependences, the concrete classes in the interfaces, but during
configuration (runtime) rather than compilation.


Uses a new
Asembler

object.



16 de mayo de 2009

Dependency Injection


The Assembler knows DataProcessor (the client), DataSource (the service interface) and
DataSourceDbImpl (the service implementation). It then will create an instance of
DataSourceDbImpl and “inject” that instance in the DataProcessor
.


+
processData
()
DataProcessor
+
getDataList
()
DataSourceDbImpl
+
getDataList
()
«interfaz»
DataSource
Assembler
<<
creates
>>
16 de mayo de 2009

Dependency Injection


This is the Assembler code and the new client:











public class Assembler {


public static DataProcessor createDataProcessor() {



DataSource source = new DataSourceDbImpl();





// setter dependency injection



DataProcessor processor = new DataProcessor();



processor.setSource(source);






// constructor dependency injection



DataProcessor processor2 = new DataProcessor(source);






return processor;


}

}

public class Client6 {


public static void main(String[] args) {



DataProcessor processor = Assembler.createDataProcessor();



processor.processData();


}

}


16 de mayo de 2009

Dependency Injection


The Assembler is the object that “connects” the dependeces. Instead of our code
looking for them (passing them by constructors, using factories, or a service locator),
now is the Assembler code that knows about the dependences, and connects them in
run time.


This is also called “inversion of control”, the control flow of the application is managed
by the framework (in this case the Assembler). DI is a kind of IoC.


If we put the information about the dependecies in a configuration file (metadata), and
name this assembler class as “Bean Factory”, we have the core of the Spring
Framework.



16 de mayo de 2009

Spring Dependency Injection


Reading SpringConfig.xml and using reflections, Spring creates DataProcessor and its
dependences.





+
processData
()
DataProcessor
+
getDataList
()
DataSourceDbImpl
+
getDataList
()
«interfaz»
DataSource
BeanFactory
<<
creates
>>
SpringConfig
.
xml
16 de mayo de 2009

Spring Dependency Injection


The dependences are defined as “beans” in a configuration file:







And this is the new client code:


<beans>


<bean id="dataProcessor" class="model7.DataProcessor">



<property name="source" ref="dataSource"/>


</bean>



<bean id="dataSource" class="model7.DataSourceDbImpl"/>


</beans>

public class Client7 {


public static void main(String[] args) {



Resource resource = new FileSystemResource("SpringConfig.xml");



BeanFactory factory = new XmlBeanFactory(resource);



DataProcessor processor = (DataProcessor) factory.getBean("dataProcessor");



processor.processData();


}

}

16 de mayo de 2009

Contents


The problem

The Spring Framework


Dependency Injection


DI Best Practices




16 de mayo de 2009

Spring Framework history


First version written by Rod Johnson,
released with the publication of his book
Expert One
-
on
-
One J2EE Design and
Development

in October 2002


Started 2002/2003 by Rod Johnson and
Juergen Holler


Spring 1.0


Released March 2004


Spring 1.2


March 2005


Spring 2.0


October 2006


Spring 2.5


November 2007


Spring 3.0


Final release in 2009

16 de mayo de 2009

Spring Mission Statement

We believe that:


J2EE

should be easier to use


It is best to program to
interfaces
, rather than classes. Spring reduces the complexity cost of using
interfaces to zero.


JavaBeans
offer a great way of configuring applications.


OO design

is more important than any implementation technology, such as J2EE.


Checked exceptions are overused

in Java. A platform shouldn't force you to catch exceptions
you're unlikely to be able to recover from.


Testability
is essential, and a platform such as Spring should help make your code easier to test.


Our philosophy is summarized in “Expert One
-
on
-
One J2EE Design and Development” by Rod
Johnson.

We aim that:


Spring should be a pleasure to use


Your application code should
not

depend on Spring APIs


Spring should not compete with good existing solutions, but should foster integration. (For example,
JDO, Toplink, and Hibernate are great O/R mapping solutions. We don't need to develop another
one.)

16 de mayo de 2009

What is Spring Framework?


Spring is a lightweight, dependency injection and aspect
-
oriented
container and framework.



Lightweight:



In terms of both
size

and
overhead
.


Entire framework can be distributed in single JAR file (2.8MB)


Processing overhead required is negligible


Also, it’s
non intrusive
: objects have no dependency on Spring specific classes



Dependency Injection:


Promotes
loose coupling

through use of DI


Instead of an object looking up dependencies from a container, the container gives
the dependencies to the object at instantiation without waiting to be asked

16 de mayo de 2009

What is Spring Framework?


Aspect
-
oriented
:


Enables
cohesive development

by separating application business logic from
system services (cross
-
cutting concerns).


Application objects focus on business logic not other system concerns such as
logging, transaction management, etc.


Container:


It
contains and manages the life cycle

of application objects.


You can declare how each object should be created, configured, and associated
with each other.


Framework:


Provides
infrastructure functionality

(transaction management, persistence
framework integration, etc.), leaving the development of application to you.


Spring makes it possible to configure and compose complex applications from
simpler components.

16 de mayo de 2009

Spring Modules

16 de mayo de 2009

Spring Modules

1. Spring Core module


It’s the most fundamental part of the framework and provides Dependency Injection
features


Defines how beans are created, configured, and managed

more of the nuts
-
and
-
bolts of Spring.


Here you’ll find Spring’s BeanFactory, the heart of any Spring
-
based application


16 de mayo de 2009

Spring Modules

2. Spring Context module


The core module’s BeanFactory makes Spring a container, but the context module is
what makes it a framework.


Build on the solid base provided by the Core and Beans modules.


Adds support for internationalization (I18N), event
-
propagation, resource
-
loading,
and the transparent creation of contexts by, for example, a servlet container.


Supplies support for some Java EE features EJB, JMX, email, and remoting.

16 de mayo de 2009

Spring Modules



3. Spring AOP module


Provides an AOP Alliance
-
compliant aspect
-
oriented programming implementation


Serves as the basis for developing your own aspects for your Spring
-
enabled
application.


Ensures interoperability between Spring and other Java AOP frameworks


Supports metadata programming (aspects can be configured using annotations)

16 de mayo de 2009

Spring Modules



4. Spring DAO module


Working with JDBC often results in a lot of boilerplate code: gets a connection,
creates a statement, processes a result set, and closes the connection.


Abstracts away the boilerplate code and prevents problems that result from a failure
to close database resources


Also build a layer of meaningful runtime exceptions on top of the errors given by
database servers


Uses Spring AOP module to provide Transaction management services

16 de mayo de 2009

Spring Modules


5. Spring ORM module


Provide integration with several popular ORM frameworks, including Hibernate, JPA,
JDO, and iBATIS SQL Maps.


Spring’s transaction management supports each of these ORM frameworks as well
as JDBC.


16 de mayo de 2009

Spring Modules



6. Spring Web module


Builds on the application context module.


Support for several web
-
oriented tasks as multipart file uploads and programmatic
binding of request parameters to your business objects.


Integration support with Struts and JSF.

16 de mayo de 2009

Spring Modules



7. Spring MVC module


Spring’s MVC framework: promotes Spring’s loosely coumpled techniques in the web
layer.

16 de mayo de 2009

Distribution JAR files


spring
(~2870 KB): convenient jar file combining all standard modules (except for the test module
and the Spring MVC support)


spring
-
core
(~280 KB): core abstractions and utilities, source
-
level metadata support, repackaged
ASM library


spring
-
beans
(~480 KB): JavaBeans support, bean container


spring
-
context
(~465 KB): application context, JNDI, JMX, instrumentation, remoting, scripting,
scheduling, validation
-



spring
-
aop
(~320 KB): AOP framework


spring
-
context
-
support
(~95 KB): Quartz and CommonJ scheduling, UI templating, mail, caching


spring
-
jdbc
(~330 KB): JDBC support


spring
-
tx
(~225 KB): transaction infrastructure, JCA support, DAO support


spring
-
orm
(~370 KB): JDO support, JPA support, Hibernate support, TopLink support, iBATIS
support


spring
-
jms
(~190 KB): JMS 1.0.2/1.1 support


spring
-
web
(~190 KB): web application context, multipart resolver, HTTP
-
based remoting support


spring
-
webmvc

(~395 KB): framework servlets, web MVC framework, web controllers, web views


spring
-
webmvc
-
portlet

(~150 KB): framework portlets, portlet MVC framework, portlet controllers


spring
-
webmvc
-
struts

(~35 KB): Struts 1.x action support, Tiles 1.x view support


spring
-
test
(~180 KB): test context framework, JUnit support, JNDI mocks, Servlet API mocks,
Portlet API mocks

16 de mayo de 2009

The Spring Triangle

Spring is essentially a technology dedicated to enabling you to build applications
using POJOs.

16 de mayo de 2009

Contents


The problem


The Spring Framework

Dependency Injection


DI Best Practices




16 de mayo de 2009

Spring IoC/DI Container

16 de mayo de 2009

BeanFactory and ApplicationContext

16 de mayo de 2009

Spring Container



Two types of containers


bean factory


simplest of containers, providing basic support for DI.


To
retrieve a bean from a BeanFactory
, call the getBean() method, passing the ID of the
bean you want to retrieve: MyBean myBean = (MyBean) factory.getBean("myBean");


When
getBean()
is called, the factory will instantiate the bean and set the bean’s
properties (
lazy loading
)


application context


build on the notion of a bean factory by providing application framework services, such as
the ability to resolve textual messages from a properties file and the ability to publish
application events to interested event listeners.


An application context
preloads all singleton beans
upon context startup.


Types of injection
:


Constructor injection


Setter injection


Bean scoping
: singleton (single instance, the default), prototype (once instance per
use), request, session, global
-
sesion.

16 de mayo de 2009

Spring Container


The dependences are defined as “beans” in a configuration file:







Using the Spring Factory:






Using Application Context:


<beans>


<bean id="dataProcessor" class="model7.DataProcessor">



<property name="source" ref="dataSource"/>


</bean>



<bean id="dataSource" class="model7.DataSourceDbImpl"/>


</beans>

Resource resource = new FileSystemResource("SpringConfig.xml");

BeanFactory factory = new XmlBeanFactory(resource);

DataProcessor processor = (DataProcessor) factory.getBean("dataProcessor");

ApplicationContext ctx = new FileSystemXmlApplicationContext("SpringConfig.xml");

DataProcessor processor = (DataProcessor) ctx.getBean("dataProcessor");

16 de mayo de 2009

Spring Container



Externalizing the confituration


If you use an Application Context container, you can enable the
PropertyPlaceholderConfigurer feature, to tell Spring to load certain configuration
from an external property file.


To enable this feature, configure the following bean:









And use them in the beans

<bean id="propertyConfigurer”










class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">


<property name="locations">



<list>




<value>jdbc.properties</value>




<value>security.properties</value>



</list>


</property>

</bean>

16 de mayo de 2009

Spring Container



Example:


For the JDBC properties in jdbc.properties:






And then, the data source bean:

database.driverClassName=oracle.jdbc.driver.OracleDriver

database.url=jdbc:oracle:thin:@127.0.0.1:1521:XE

database.username=myUser

database.password=myPassword

<bean id="dataSource“ class="org.apache.commons.dbcp.BasicDataSource“>


<property name="driverClassName“ value=“${database.driverClassName}"/>


<property name=“url“ value=“${database.url}"/>


<property name=“username“ value=“${database.username}"/>


<property name=“password“ value=“${database.password}"/>

</bean>

16 de mayo de 2009

Spring Container



Why...
bean
?


The motivation for using the name
'bean'
, as opposed to
'component'
or
'object'
is
rooted in the origins of the Spring Framework itself (it arose partly as a response to
the complexity of Enterprise Java
Beans
).



BeanFactory or ApplicationContext?


A BeanFactory pretty much just instantiates and configures beans.


An ApplicationContext also does that,
and
it provides the supporting infrastructure
to enable
lots
of enterprise
-
specific features such as transactions and AOP.


In short, favor the use of an ApplicationContext.



Constructor
-

or Setter
-
based DI?


The Spring team generally advocates the usage of setter injection.


Easy management of optional properties, setters are inherited, not many
constructors.

16 de mayo de 2009

Contents


The problem


The Spring Framework


Dependency Injection

DI Best Practices



16 de mayo de 2009

Best Practices


Avoid using autowiring


Sacrifices the explicitness and maintainability of the configurations.


<bean id="orderService"




class="com.spring.OrderService"




autowire="byName"/>


Use naming conventions


You can follow the Java class field name convention. The bean ID for an instance of
OrderServiceDAO would be orderServiceDAO .


Use shortcut forms


Is less verbose, since it moves property values and references from child elements into
attributes.

<bean id="orderService“ class="com.spring.OrderService">


<property name="companyName">



<value>tcs</value>


</property>

<bean>


<bean id="orderService“ class="com. spring.OrderService">


<property name="companyName“ value=“tcs”/>

<bean>


16 de mayo de 2009

Best Practices


Reuse bean definitions, if possible


A child bean definition can inherit configuration information from its parent bean, which
essentially serves as a template for the child beans.


Use ids as bean identifiers


You can specify either an id or name as the bean identifier, using ids can leverage the
XML parser to validate the bean references.


Prefer setter injection over constructor injection


Constructor injection can ensure that a bean cannot be constructed in an invalid state,
but setter injection is more flexible and manageable, especially when the class has
multiple properties and some of them are optional.


Do not abuse dependency injection


Not all Java objects should be created through dependency injection. As an example,
domain objects should not be created through ApplicationContext. Overuse of
dependency injection will make the XML configuration more complicated and bloated.
With IDEs such as Eclipse Java code is much easier to read, maintain, and manage
than XML files.

16 de mayo de 2009

Best Practices


Don’t place all your beans in one xml file


Split the configuration in different xml files, long xml files are hard to read. Minimal one
xml file per architectural layer, for example applicationContext
-
dao.xml,
applicationContext
-
service.xml, etc.


Use Spring IDE plug
-
in


Basically, makes Spring’s XMLs manipulation human friendly. Some features are:


XML editor for Spring beans configuration files, allows to navigate the beans


Incremental builder which validates all modified Spring bean config files defined in a Spring
project.


Java refactorings for Bean class rename and move and property rename


View which displays a tree with all Spring projects and their Spring bean config files


Image decorator which decorates all Spring projects, their bean config files and all Java classes
which are used as bean classes


Graph which shows all beans (and their relationships) defined in a single config file or a config
set


Extension of Eclipse's search facility to search for beans


Wizard for creating a new Spring project

16 de mayo de 2009

Best Practices

16 de mayo de 2009

45






Thank You