The Spring Framework

advertisement
Spring Framework
Eliminating Enterprise Java Complexity
Buenos Aires, May 2009.
16 de mayo de 2009
Contents
 The problem
 The Spring Framework
 Dependency Injection
 Aspect-Oriented Programming
 Portable Service Abstractions
 Best Practices
16 de mayo de 2009
Contents
The problem
 The Spring Framework
 Dependency Injection
 Aspect-Oriented Programming
 Portable Service Abstractions
 Best Practices
16 de mayo de 2009
Working with dependencies
DataProcessor
DataSource
+processData()
+getDataList()
Data
-info : String
+getInfo()
+setInfo()
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.
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
DataProcessor
Data
«interfaz»
DataSource
+getDataList()
+processData()
-info : String
+getInfo()
+setInfo()
<<creates>>
DataSourceDbImpl
+getDataList()
public interface DataSource {
List<Data> getDataList();
DataSourceXmlImpl
+getDataList()
DataSourceWSImpl
+getDataList()
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);
}
}
}
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
Solution 1 – Using a Constructor
•
Passing the DataSource service implementation as a constructor parameter to the
DataProcessor. Changin this client:
public class Client1 {
public static void main(String[] args) {
DataProcessor processor = new DataProcessor();
processor.processData();
}
}
•
To this one:
public class Client3 {
public static void main(String[] args) {
DataSource source = new DataSourceDbImpl();
DataProcessor processor = new DataProcessor(source);
processor.processData();
}
}
•
But we have now the dependece in the client… It’s a new problem.
16 de mayo de 2009
Solution 2 – Abstract Factory Patter
•
•
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:
public class Client4 {
public static void main(String[] args) {
DataProcessorFactory factory = new DataProcessorFactoryDbImpl();
DataSource source = factory.createDataSource();
DataProcessor processor = new DataProcessor(source);
processor.processData();
}
}
•
•
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.
16 de mayo de 2009
Solution 3 – Service Locator Pattern
•
•
We will have the same problem with the service locator pattern.
We pass a parameter in the constructor, indicanting the concrete data service.
public class Client5 {
public static void main(String[] args) {
DataProcessor processor = new DataProcessor(ServiceLocator.DB);
processor.processData();
}
}
•
The DataProcessor use 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 find of data source we want in the client, if we want to
change it, we have to change the client.
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 Patter: “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 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.
DataProcessor
+processData()
«interfaz»
DataSource
+getDataList()
DataSourceDbImpl
+getDataList()
<<creates>>
Assembler
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 connect 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, 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.
DataProcessor
+processData()
«interfaz»
DataSource
+getDataList()
DataSourceDbImpl
SpringConfig.xml
+getDataList()
<<creates>>
BeanFactory
16 de mayo de 2009
Spring Dependency Injection
•
The dependences are defined as “beans” in a configuration file:
<beans>
<bean id="dataProcessor" class="model7.DataProcessor">
<property name="source" ref="dataSource"/>
</bean>
<bean id="dataSource" class="model7.DataSourceDbImpl"/>
</beans>
•
And this is the new client code:
public class Cliente7 {
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
 Aspect-Oriented Programming
 Portable Service Abstractions
 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
•
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:
– Spring makes it possible to configure and compose complex applications from
simpler components.
– Provides infrastructure functionality (transaction management, persistence
framework integration, etc.), leaving the development of application to you.
16 de mayo de 2009
Spring Modules
16 de mayo de 2009
Spring Modules
•
1. 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 nutsand-bolts of Spring.
– Here you’ll find Spring’s BeanFactory, the heart of any Spring-based application
•
2. Application 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 basic
remoting support.
16 de mayo de 2009
Spring Modules
•
3. 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)
•
4. 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. ORM Integration module
– Provide hooks into several popular ORM frameworks, including Hibernate, JDO,
and iBATIS SQL Maps.
– Spring’s transaction management supports each of these ORM frameworks as
well as JDBC.
•
6. 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 Jakarta Struts and JSF.
•
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, validationspring-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
 Aspect-Oriented Programming
 Portable Service Abstractions
 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:
<beans>
<bean id="dataProcessor" class="model7.DataProcessor">
<property name="source" ref="dataSource"/>
</bean>
<bean id="dataSource" class="model7.DataSourceDbImpl"/>
</beans>
•
Using the Spring Factory:
Resource resource = new FileSystemResource("SpringConfig.xml");
BeanFactory factory = new XmlBeanFactory(resource);
DataProcessor processor = (DataProcessor) factory.getBean("dataProcessor");
•
Using Application Context:
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:
<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>
– And use them in the beans
16 de mayo de 2009
Spring Container
•
Example:
– For the JDBC properties in jdbc.properties:
database.driverClassName=oracle.jdbc.driver.OracleDriver
database.url=jdbc:oracle:thin:@127.0.0.1:1521:XE
database.username=myUser
database.password=myPassword
– And then, the data source bean:
<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 JavaBeans).
•
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
Aspect-Oriented Programming
 Portable Service Abstractions
 Best Practices
16 de mayo de 2009
What is AOP?
•
•
•
Java doesn’t offer an easy way to remove code duplication among classes that
aren’t in the same hierarchy.
AOP is a paradigm for modularizing crosscutting code, a way to remove
duplicated code.
Code that would otherwise be scattered across multiple methods or objects can
be gathered in one place
16 de mayo de 2009
What is AOP?
Calls to system-wide concerns such as logging and security are often scattered about in
modules where those concerns are not their primary concern
16 de mayo de 2009
What is AOP?
Using AOP, system wide concerns blanket the components that they impact.This leaves
the application components to focus on their specific business functionality.
16 de mayo de 2009
Before AOP
Client
Method
1. Security check
2. Obtain session
3. Log it to the file
4. Audit trail
5. Start transaction
6. Business Logic
7. Commit
8. Exception handling
16 de mayo de 2009
AOP applied
1.
2.
3.
4.
5.
Security check
Obtain session
Log it to the file
Audit trail
Start transaction
Method
1. Business Logic
Client
1.
Commit
1.
Exception handling
16 de mayo de 2009
AOP Terms
•
•
•
•
•
•
•
Join point: a particular point of execution where the aspect can be plugged in. For
example a method being called, or the handling of an exception.
Advice: it is the code to execute. For example, starting a transaction, or the logging
code. It is inserted into our application at pointcut.
Pointcut : represents which join point an advice should be applied to. For example
every method starting with "insert", "delete", "update“.
Aspect : pointcuts + advices form an aspect. For example start a transaction in
methods which need to run in a transactional context.
Target: the class being advised by some aspects .
Proxy: the object created by AOP framework after applying advice to the target object.
Weaving: applying an aspect.
16 de mayo de 2009
Spring AOP elements
•
•
•
•
•
Aspects are written in Java.
Pointcut are written in XML in Spring Configuration File.
Spring supports only method joinpoints (it doesn’t support constructor or properties
jointpoint as AspectJ).
Aspects are implemented as proxies that wrap the target object. The proxy handles
method calls, performs additional aspect logic, and then invokes the target method.
When an aspect is applied to an object, a particular advice will be applied to any join
point matching a pointcut's expression.
16 de mayo de 2009
Advice Types in Spring
•
Depending on the advice type, the interface that has to be implemented:
•
Before advice: executes before a join point. MethodBeforeAdvice.
•
After returning advice: executes after a join point completes without throwing
exceptions. AfterReturningAdvice.
•
After throwing advice: executes after a join point has thrown an exception.
ThrowsAdvice.
•
Around advice: executes before and after a join point is executed. MethodInterceptor.
16 de mayo de 2009
Spring AOP example
•
Our code, service interface and implementation:
public interface Counter {
public void go();
}
public class CounterImpl implements Counter {
public void go() {
for(int i = 0; i <= 10; i++) {
System.out.println("counter = " + i);
}
}
}
16 de mayo de 2009
Spring AOP example
•
The advice:
public class LoggingAdvice implements MethodBeforeAdvice, AfterReturningAdvice {
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("**** HI !!! ****");
}
public void afterReturning(Object returnValue, Method method, Object[] args,
Object target) throws Throwable {
System.out.println("**** GOODBYE!!! ****");
}
}
16 de mayo de 2009
Spring AOP example
•
Spring’s configuration file (I):
<beans>
<bean id="loggingAdvice" class="model8.LoggingAdvice" />
<bean id="loggingPointcut“
class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value=".*go" />
</bean>
<bean id="loggingAdvisor“
class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="loggingAdvice" />
<property name="pointcut" ref="loggingPointcut" />
</bean>
<bean id="counterTarget" class="model8.CounterImpl" />
<bean id="counter" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="counterTarget" />
<property name="interceptorNames" value="loggingAdvisor" />
<property name="proxyInterfaces" value="model8.Counter" />
</bean>
</beans>
16 de mayo de 2009
Spring AOP example
•
Spring’s configuration file with Autoproxy (II):
<beans>
<bean id="loggingAdvice" class="model8.LoggingAdvice" />
<bean id="loggingPointcut“
class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value=".*go" />
</bean>
<bean id="loggingAdvisor“
class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="loggingAdvice" />
<property name="pointcut" ref="loggingPointcut" />
</bean>
<bean id="counter" class="model8.CounterImpl" />
<bean class="org.springframework.aop.framework.autoproxy.
DefaultAdvisorAutoProxyCreator"/>
</beans>
16 de mayo de 2009
Pure-POJO Ascpects
•
•
•
Spring 2.0 has new XML configuration elements in the aop namespace, that make it
simple to turn any class into an aspect. They beginning tag is <aop:config>, specifying
the aspect with <aop:aspect>.
You do not need to specify or modify the source code of the class that is going to
provide the aspect’s functionality, <aop:aspect> can reference any bean.
The value given to the pointcut attribute is a pointcut defined in AspectJ’s pointcut
expression syntax:
16 de mayo de 2009
Pure-POJO Ascpects
•
Spring’s configuration file, making an aspect from the logging POJO (III):
<aop:config>
<aop:aspect ref="logging">
<aop:before method="sayHi" pointcut="execution(* *.*(..))" />
<aop:after-returning method="sayGoodbye" pointcut="execution(* *.*(..))"/>
</aop:aspect>
</aop:config>
•
You can also create a pointcut to reutilize the code:
<aop:config>
<aop:pointcut id="myPointcut" expression="execution(* *.*(..))"/>
<aop:aspect ref="logging">
<aop:before method="sayHi" pointcut-ref="myPointcut" />
<aop:after-returning method="sayGoodbye" pointcut-ref="myPointcut" />
</aop:aspect>
</aop:config>
16 de mayo de 2009
Pure-POJO Ascpects
•
The new logging advice is now a POJO:
public class Logging {
public void sayHi() {
System.out.println("**** HI!!! ****");
}
public void sayGoodbye() {
System.out.println("**** GOODBYE!!! ****");
}
}
16 de mayo de 2009
Spring AOP example
•
Console output:
**** HI!!! ****
counter = 0
counter = 1
counter = 2
counter = 3
counter = 4
counter = 5
counter = 6
counter = 7
counter = 8
counter = 9
counter = 10
**** GOODBYE!!! ****
16 de mayo de 2009
Declarative transactions with AOP
•
AOP example: this wraps a transaction interceptor around a DAO
<bean id="daoBeanTarget" class="org.example.dao.impl.DaoImpl">
<property name="sessionFactory“ ref="mySessionFactory"/>
</bean>
<bean id="daoBean"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
<property name="target" ref="daoBeanTarget"/>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
16 de mayo de 2009
Advantages and Drawbacks of AOP
•
•
Advantages
– Decoupling between classes
– A clear line between the different application layers
– Reduction of code duplication
– Better support for refactoring
– The first goal of Spring’s AOP support is to provide portable J2EE services to
POJOs.
Drawbacks
– AOP configuration and code is not highly visible.
– It could be dificult to understand and debug the code.
– Important: business logic should remain in application’s code, put in AOP only
cross-cutting concerns.
16 de mayo de 2009
Contents
 The problem
 The Spring Framework
 Dependency Injection
 Aspect-Oriented Programming
Portable Service Abstractions
 Best Practices
16 de mayo de 2009
Portable Service Abstractions
•
Consistent integration with various standard and 3rd party APIs.
•
Allows access to these frameworks without knowing how they actually work.
•
Spring provides abstraction and integration for:
– Transaction Management: JTA, JDBC, others
– Data Access: JDBC, Hibernate, JDO, TopLink, iBatis
– Email
– Remoting
– EJB, Web Services, RMI
– Integrates nicely with Struts, JSF, Tapestry, Velocity and other web frameworks
•
Spring also provides it’s own web framework, Spring Web MVC
16 de mayo de 2009
Portable Service Abstractions
Benefits:
•
Insulates you from the underlying APIs
•
Greater reusability
•
Spring abstractions always consist of interfaces
•
This makes testing simpler
•
For data access, Spring uses a generic transaction infrastructure and DAO exception
hierarchy that is common across all supported platforms
16 de mayo de 2009
Spring integration with Hibernate
•
Define a DataSource bean
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:XE"/>
<property name="username" value=“pepe"/>
<property name="password" value=“1234"/>
</bean>
•
Define a Session Factory bean
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="annotatedClasses">
<list>
<value>demo.entity.Contact</value>
</list>
</property>
<property name="dataSource“ ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
</props>
</property>
</bean>
16 de mayo de 2009
Spring integration with Hibernate
•
Define an Hibernate Template bean
<bean id="hibernateTemplate“ class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
•
Define a Transaction Manager bean
<bean id="transactionManager“
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
•
Define a Parent DAO bean for CRUD operations
<bean id="baseDao" abstract="true" class="demo.dao.HibernateGenericDAO">
<property name="hibernateTemplate" ref="hibernateTemplate" />
</bean>
16 de mayo de 2009
Spring integration with Hibernate
•
Define an Transaction Proxy Template bean
<bean id="parentService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true">
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
•
Service interface and implementation
<bean id="contactServiceImpl" class="demo.service.impl.ContactServiceImpl">
<property name="contactDAO" ref="contactDAOImpl"/>
</bean>
<bean id="contactService" parent="parentService">
<property name="target" ref="contactServiceImpl"/>
<property name="proxyInterfaces" value="demo.service.ContactService" />
</bean>
16 de mayo de 2009
Spring integration with Hibernate
•
DAO interface and implementation
<bean id="contactDAOImpl" class="demo.dao.impl.HibernateContactDAO" parent="baseDao" />
<bean id="contactDAO" parent="parentService">
<property name="target" ref="contactDAOImpl" />
</bean>
16 de mayo de 2009
Contents
 The problem
 The Spring Framework
 Dependency Injection
 Aspect-Oriented Programming
 Portable Service Abstractions
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
Why use Spring?
•
Spring can effectively organize your middle tier objects, whether or not you choose to
use EJB.
•
Spring can eliminate the proliferation of Singletons seen on many projects.
•
Spring can eliminate the need to use a variety of custom properties file formats, by
handling configuration in a consistent way throughout applications and projects.
•
Spring can facilitate good programming practice by reducing the cost of
programming to interfaces, rather than classes, almost to zero.
•
Spring is designed so that applications built with it depend on as few of its APIs as
possible.
•
Applications built using Spring are very easy to unit test.
16 de mayo de 2009
Why use Spring?
•
Spring can make the use of EJB an implementation choice, rather than the
determinant of application architecture.
•
Spring helps you solve many problems without using EJB. For example, using AOP
to deliver declarative transaction management without using an EJB container.
•
Spring provides a consistent framework for data access, whether using JDBC or an
O/R mapping product such as TopLink, Hibernate or a JDO implementation.
•
Spring provides a consistent, simple programming model in many areas, making it an
ideal architectural "glue."
Spring is essentially a technology dedicated to enabling you to build applications
using POJOs.
16 de mayo de 2009
Resource
16 de mayo de 2009
Thank You
16 de mayo de 2009
69
Download