Rrahman 320 Spring Framework
Rrahman 320 Spring Framework
Spring Framework
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
@Service
public class BidService {
@PersistenceContext
private EntityManager entityManager;
Java EE Interceptor
@Stateless
public class BidService {
@Legacy private BidDao bidDao;
Annotated method intercepted
@Audited
public void addBid(Bid bid) {
bidDao.addBid(bid);
}
}
@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 {}
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
11
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
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
14
Facelet
15
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
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
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
19
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
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
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
23
@Remote
@WebService
public interface BidService {
void addBid(Bid bid);
}
25
26
Java EE Scheduling
29
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
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
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
33
@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
35
36
37
Summary
z
38
39