0% found this document useful (0 votes)
22 views39 pages

Rrahman 320 Spring Framework

Java EE and the Spring Framework are both capable middleware solutions. Java EE 5 adopts ideas, as well as annotations and convention-over-configuration. The Spring Framework is a fully integrated platform with strong intelligent defaulting and minimal configuration.

Uploaded by

anaga1982
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views39 pages

Rrahman 320 Spring Framework

Java EE and the Spring Framework are both capable middleware solutions. Java EE 5 adopts ideas, as well as annotations and convention-over-configuration. The Spring Framework is a fully integrated platform with strong intelligent defaulting and minimal configuration.

Uploaded by

anaga1982
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 39

1

JBoss World 2009 | Reza Rahman

Java EE and the Spring Framework:


Compare/Contrast
Reza Rahman
Independent Consultant
September 2009

JBoss World 2009 | Reza Rahman

A Quick Glance Back


z

Java EE pioneers most innovations in server-side Java

A widely deployed but much maligned platform

Spring, along with Hibernate, brings POJO


programming, IoC and testability to the mainstream
Java EE 5 adopts ideas, as well as annotations and
convention-over-configuration
Hibernate standardized into JPA, Spring remains nonstandard but adopts Java EE features to a degree
Java EE 6 matures ideas in Java EE 5 in addition to
pruning and profiles
CDI, JSF 2, JPA 2, EJB 3.1, Servlet 3, JAX-RS major
API changes
JBoss World 2009 | Reza Rahman

The Birds-Eye View


Java EE and Spring are both capable middleware
solutions
Functionally equivalent for the most part, with very different
approaches
For very vanilla applications, code is almost identical
Java EE

Spring Framework

Fully integrated platform with strong intelligent defaulting


and minimal configuration (convention-over-configuration)
Non-redundant APIs with specialized roles
Focus on annotations for meta-data and type-safety
Widely supported open standard
Vendor and platform agnostic code
Integration with non-standard technologies left to vendors
Vendors free to innovate via non-standard extensions and
value-added features like clustering, HA, administration,
monitoring, development/deployment tools

Explicit configuration, typically through XML


More flexibility for fine-grained control but more complexity
Ease-of-use abstractions over lower-level, general purpose
APIs like JDBC, JMS and JavaMail
Non-standard open source technology from a commercial
vendor
Integration with standard as well as non-standard
technologies that are often overlapping
Portability across runtime platforms at the risk of vendor
lock-in

There is no practical reason to be forced to


choose between the two
Balanced competition in server-side Java is
good for both developers and vendors
There are excellent integration possibilities

JBoss World 2009 | Reza Rahman

Features/APIs Overview
Java EE

Dependency
Injection

JSR 250

JSR 330

AOP

Interceptor

Decorator

Persistence

JPA 2

Transactions

JTA

Presentation
Framework

JSF 2

Web Services

JAX-WS

Security

Spring Framework

CDI

Spring IoC
Container

Spring
AOP

AspectJ

JPA

Hibernate

JDBC

iBATIS

TopLink

JDO

JTA

JDBC

JPA

Hibernate

TopLink

JDO

JSF

Struts

Spring
MVC

Tapestry

WebWork

JAX-RS

JAX-WS

XFire

Spring
MVC REST

JAX-RPC

JAAS

EJB 3.1

Spring
Security

Messaging

JMS

EJB 3.1

JMS

Remoting

RMI

EJB 3.1

RMI

HTTP

Burlap

Hessian

Scheduling

EJB 3.1

Quartz

JDK Timer

EJB 3.1

JBoss World 2009 | Reza Rahman

Java EE Basic Business Component


@Stateless
The bean is thread-safe; using non
public class BidService { thread-safe resources requires no
special precautions
@PersistenceContext
private EntityManager entityManager;
public void addBid(Bid bid) {
entityManager.persist(bid);
}
}

JBoss World 2009 | Reza Rahman

All business methods are


transactional by default.

Spring Basic Business Component


Bean has no thread-safety guarantees,
all resources must be thread-safe.

@Service
public class BidService {
@PersistenceContext
private EntityManager entityManager;

Transactions must be specified explicitly


@Transactional
public void addBid(Bid bid) {
entityManager.persist(bid);
}

JBoss World 2009 | Reza Rahman

Spring specific data access APIs


handle thread-safe behind scenes, like
non-standard entity manager proxy.

Spring Basic Business Component Configuration


<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" Schemas reduce configuration
burden, but still can be hard to
xmlns:aop="http://www.springframework.org/schema/aop"
understand, debug, maintain
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<context:component-scan base-package="com.actionbazaar"/>
<tx:annotation-driven/>
Annotation driven configuration helps
greatly if you are not a fan of XML
...
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
Explicit, fine-grained container configuration
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="loadTimeWeaver">
<bean
class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
May or may not be needed depending
on the JPA provider.
</bean>
</beans>
8

JBoss World 2009 | Reza Rahman

Java EE Interceptor
@Stateless
public class BidService {
@Legacy private BidDao bidDao;
Annotated method intercepted

@Audited
public void addBid(Bid bid) {
bidDao.addBid(bid);
}
}

Interceptor to handle the


annotation

@Interceptor @Audited
public class AuditInterceptor {
@AroundInvoke
public Object audit(InvocationContext context) {
System.out.println("Executing: "
+ context.getMethod().getName());
return context.proceed();
}
}
Binds the annotation to
@InterceptorBindingType
an interceptor
@Target({TYPE, METHOD})
@Retention(RUNTIME)
public @interface Audited {}

JBoss World 2009 | Reza Rahman

Spring Aspects
@Service
public class BidService {
@Autowired @Legacy private BidDao bidDao;
The annotation by itself does
not mean anything

@Audited
@Transactional
public void addBid(Bid bid) {
bidDao.addBid(bid);
}
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Audited {}
@Component
More fine-grained interception,
@Aspect
but more complex syntax
public class AuditAspect {
@Before("execution(public * *(..)) && @annotation(Audited)")
public void audit(JoinPoint joinPoint) {
System.out.println("Entering: " + joinPoint);
}
}
10

JBoss World 2009 | Reza Rahman

Spring Aspects Configuration

11

JBoss World 2009 | Reza Rahman

Java EE Injection
@Stateless
public class BidService {
@Legacy private BidDao bidDao;
...
Qualified injection
}
@Legacy @Dao
public class NativeSqlBidDao implements BidDao {
...
}
@ApplicationScoped
@Profiled
@CurrencyConverted(Currency.USD)
@Stereotype
Grouping metadata
via stereotypes
@Target(TYPE)
@Retention(RUNTIME)
public @interface Dao {}
@BindingType
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface Legacy {}
12

JBoss World 2009 | Reza Rahman

Spring Injection
Spring stereotype concept simply loads
a component to the registry.

@ActionBazaarService
public class BidService {
@Autowired @Legacy private BidDao bidDao;
...
Qualified injection
}

@Legacy @Repository
public class NativeSqlBidDao implements BidDao {
...
}
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface Legacy {}

13

JBoss World 2009 | Reza Rahman

Spring Injection Configuration


<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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
...
<context:component-scan base-package="com.actionbazaar">
<context:include-filter type="annotation"
expression="com.actionbazaar.ActionBazaarService"/>
</context:component-scan>
Including the new component type
...
</beans>

14

JBoss World 2009 | Reza Rahman

Facelet

15

JBoss World 2009 | Reza Rahman

Facelet Component
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:composite="http://java.sun.com/jsf/composite">
<body>
Component interface
<composite:interface>
<composite:actionSource name="bidEvent"/>
</composite:interface>
Component implementation
<composite:implementation>
<p>Item: <h:outputText value=#{item.name}/></p>
<p>Current bid: <h:outputText
value=#{item.highestBid.amount}/></p>
<p>Amount: <h:inputText id="amount"
EL binding expression to beans
value="#{bid.amount}"/></p>
<p><h:commandButton id="bidEvent" value="Add bid"/>
</composite:implementation>
</body>
</html>
16

JBoss World 2009 | Reza Rahman

Entity
Assigns name used for
@Named
EL binding.
@Entity
@Table(name=BIDS)
public class Bid {
@Id
@GeneratedValue
private long id;

@ManyToOne
@NotNull
private User bidder;
@ManyToOne
@NotNull
private Item item;
Bean validation constraints

@Min(1)
private double amount;
...
}
17

JBoss World 2009 | Reza Rahman

JSF Event Handler

Qualified injection

@Named
@RequestScoped
public class BidManager {
@Current private BidService bidService;
@LoggedIn private User user;
@SelectedItem private Item item;
@Current private Bid bid;
public String addBid() {
bid.setBidder(user);
bid.setItem(item);
bidService.addBid(bid);
return bid_confirm.xhtml;
}
}

18

JBoss World 2009 | Reza Rahman

Handling event raised


by component

Spring MVC JSP

19

JBoss World 2009 | Reza Rahman

Entity
@Entity
@Table(name=BIDS)
public class Bid {
@Id
@GeneratedValue
private long id;
@ManyToOne
private User bidder;
@ManyToOne
private Item item;
private double amount;
...
}
20

JBoss World 2009 | Reza Rahman

Spring Validator
public class BidValidator implements Validator {
public boolean supports(Class clazz) {
return Bid.class.equals(clazz);
}
public void validate(Object object, Errors errors) {
Bid bid = (Bid) object;
if (bid.getBidder() == null) {
errors.rejectValue("bidder", null, "Bidder must not be empty");
}
if (bid.getItem() == null) {
errors.rejectValue("item", null, "Item must not be empty");
}
if (bid.getAmount() < 1) {
errors.rejectValue("amount", null,
"Amount must be greater than one");
}
}
}
21

JBoss World 2009 | Reza Rahman

Spring Controller
@Controller
@RequestMapping("/add_bid.do")
@SessionAttributes("item")
@SessionAttributes("bid")
public class BidController {
@Autowire private ItemService itemService;
@Autowire private BidService bidService;
@Autowire private BidValidator bidValidator;
@RequestMapping(method=RequestMethod.GET)
public String setupForm(@RequestParam("itemId") int itemId, ModelMap model) {
Item item = itemService.getItem(itemId);
model.addAttribute("item", item);
Bid bid = new Bid();
model.addAttribute(bid, bid);
return "add_bid";
}
@RequestMapping(method=RequestMethod.POST)
public String addBid(@ModelAttribute("item") Item item, @ModelAttribute("bid") Bid bid,
HttpSession session, BindingResult result, SessionStatus status) {
bid.setBidder((User)session.getAttribute(user));
bid.setItem(item);
bidValidator.validate(bid, result);
if (result.hasErrors()) {
return "add_bid";
} else {
bidService.addBid(bid);
status.setComplete();
return "redirect:confirm_bid.do?itemId=" + item.getItemId();
}
}
}

22

JBoss World 2009 | Reza Rahman

Spring MVC Configuration

23

JBoss World 2009 | Reza Rahman

Spring MVC web.xml Configuration


<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:**/applicationContext*.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>actionbazaar</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>actionbazaar</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>jsp/index.jsp</welcome-file>
</welcome-file-list>
</web-app>
24

JBoss World 2009 | Reza Rahman

Java EE Remoting and Web Services


@Stateless
public class DefaultBidService implements BidService {
@PersistenceContext
private EntityManager entityManager;
public void addBid(Bid bid) {
entityManager.persist(bid);
}
}

No further configuration needed; A


JAX-RS (REST) end-point could
have been added here too.

@Remote
@WebService
public interface BidService {
void addBid(Bid bid);
}

25

JBoss World 2009 | Reza Rahman

Spring Remoting and Web Services


@Service
@WebService
public class DefaultBidService implements BidService {
@PersistenceContext
private EntityManager entityManager;
@Transactional
public void addBid(Bid bid) {
entityManager.persist(bid);
}
}
public interface BidService {
void addBid(Bid bid);
}

26

JBoss World 2009 | Reza Rahman

Spring Remoting and Web Services Configuration


<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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:ws="http://jax-ws.dev.java.net/spring/core"
xmlns:wss="http://jax-ws.dev.java.net/spring/servlet"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://jax-ws.dev.java.net/spring/core
http://jax-ws.dev.java.net/spring/core.xsd
http://jax-ws.dev.java.net/spring/servlet
http://jax-ws.dev.java.net/spring/servlet.xsd">
...
<wss:binding url="/bidService">
<wss:service>
Configuration via JAX<ws:service bean="#defaultBidService"/>
WS RI schema
</wss:service>
</wss:binding>
<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
<property name="serviceName" value="bidService"/>
<property name="service" ref="defaultBidService"/>
<property name="serviceInterface" value="com.actionbazaar.BidService"/>
</bean>
More traditional Spring
</beans>
exporter for remoting
27

JBoss World 2009 | Reza Rahman

Spring Remoting and Web Services web.xml


Configuration
<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:**/applicationContext*.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>jaxws-servlet</servlet-name>
<servlet-class>
com.sun.xml.ws.transport.http.servlet.WSSpringServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>jaxws-servlet</servlet-name>
Need to add a mapping
for each web service
<url-pattern>/bidService</url-pattern>
</servlet-mapping>
</web-app>
28

JBoss World 2009 | Reza Rahman

The Spring container


getting bootstrapped.

Java EE Scheduling

29

JBoss World 2009 | Reza Rahman

Spring Scheduling
@Component
public class NewsLetterGenerator {
...
public void generateMonthlyNewsLetter() {
...
}
}
More fine-grained control but
<beans...>
with greater complexity.
...
<bean id="jobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="newsLetterGenerator"/>
<property name="targetMethod" value="generateMonthlyNewsLetter"/>
</bean>
<bean id="cronTrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="jobDetail"/>
<property name="cronExpression" value="0 0 0 ? JAN-MAY,SEP-NOV 3L" />
<property name="timeZone">
<bean class="java.util.TimeZone" factory-method="getTimeZone">
<constructor-arg value="America/New_York"/>
</bean>
</property>
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list><ref bean="cronTrigger"/></list>
</property>
</bean>
</beans>

30

JBoss World 2009 | Reza Rahman

Java EE Messaging
@MessageDriven(activationConfig={@ActivationConfigProperty(
propertyName="destination",
No further configuration
needed
propertyValue="jms/OrderQueue")})
public class OrderProcessor implements MessageListener {
@Current private OrderService orderService;
public void onMessage(Message message) {
try {
ObjectMessage objectMessage = (ObjectMessage) message;
Order order = (Order) objectMessage.getObject();
orderService.addOrder(order);
} catch (Exception e) {
e.printStackTrace();
}
}
}

31

JBoss World 2009 | Reza Rahman

Spring Messaging
@Component
public class OrderProcessor implements MessageListener {
@Autowired private OrderService orderService;
public void onMessage(Message message) {
try {
ObjectMessage objectMessage = (ObjectMessage) message;
Order order = (Order) objectMessage.getObject();
orderService.addOrder(order);
} catch (Exception e) {
e.printStackTrace();
}
}
}

32

JBoss World 2009 | Reza Rahman

Spring Messaging Configuration


<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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:amq="http://activemq.apache.org/schema/core"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms-2.5.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd">
...
<amq:broker useJmx="false" persistent="false">
<amq:transportConnectors>
Outside a Java EE
environment, a JMS
<amq:transportConnector uri="tcp://localhost:0" />
is configured
</amq:transportConnectors>
</amq:broker>
<amq:queue id="jms/OrderQueue" physicalName="queue.OrderQueue"/>
<amq:connectionFactory id="connectionFactory" brokerURL="vm://localhost"/>
<jms:listener-container acknowledge=transacted concurrency=3-5>
<jms:listener destination="jms/OrderQueue" ref="orderProcessor"/>
A JTA transaction must be used
for robust message handling
</jms:listener-container>
(maybe JOTM is an option?)
Each message listener
</beans>
must be configured with
the JMS container

33

JBoss World 2009 | Reza Rahman

Spring Message Producer


@Service
public class OrderService {
private JmsTemplate jmsTemplate;
private Queue queue;
@Autowired
public void setConnectionFactory(
ConnectionFactory connectionFactory) {
this.jmsTemplate = new JmsTemplate(connectionFactory);
}
@Resource(name=jms/OrderQueue)
public void setQueue(Queue queue) {
this.queue = queue;
}
Note, this is not coordinated
with any other resources
unless using JTA

@Transactional
public void sendOrder(Order order) {
this.jmsTemplate.send(queue, new MessageCreator() {
public Message createMessage(Session session)
throws JMSException {
return session.createObjectMessage(order);
}
Note, session and connection
is opened/closed per call, so
});
connection pooling is critical
}
}
34

JBoss World 2009 | Reza Rahman

Java EE Message Producer


@Stateless
DI based JMS abstractions
public class OrderService {
@OrderSession private Session session;
@OrderMessageProducer private MessageProducer producer;
public void sendOrder(Order order) {
try {
ObjectMessage message = session.createObjectMessage();
message.setObject(order);
producer.send(message);
} catch (JMSException e) {
e.printStackTrace();
}
}
}

35

JBoss World 2009 | Reza Rahman

Java EE JMS Abstraction

36

JBoss World 2009 | Reza Rahman

The Birds-Eye View Again

37

JBoss World 2009 | Reza Rahman

Summary
z

38

Both are competent middleware stacks with mostly


equivalent functionality but very different approaches
Java EE is a tightly integrated platform with intelligent
defaulting, minimal configuration and specialized, nonoverlapping APIs.
Spring is a pluggable framework with explicit
configuration, fine grained control and wide-variety of
integration with overlapping technologies
Java EE is annotation centric while Spring is XMLbound
One is an open standard, while the other is an open
source tool from a commercial vendor
JBoss World 2009 | Reza Rahman

39

JBoss World 2009 | Reza Rahman

You might also like