вход по аккаунту


Spring and RSF Fundamentals - Confluence

код для вставкиСкачать
Spring and RSF
Aaron Zeckoski
From slides by Antranig Basman
Creative Commons AttributionNonCommercial-ShareAlike 2.5 License
RSF Wiki
Explain some Spring framework basics
Describe how RSF integrates with Spring
Define basic webapp scopes
Cover basic RSF concepts
The Spring Framework
• The most significant development in Java
• Is extensively used in the wider world as a
Java “enterprise” technology
• Purpose is to organize and orchestrate the
different parts of an application, which are
packaged as “beans”
• Only have time for a quick overview
• Crucial here because
– it is used throughout large scale projects like Sakai
and Kuali as a service location framework
– It is the basis for the RSF framework
What is so important about Spring?
• Somewhat hard to convey without seeing it!
• Spring is the first “negative technology”
– stays invisible in your code
– works hard to hide dependencies on other
technologies as well
• Solidly separates code from configuration,
making it easy to work with extremely large
• Dependency injection is a deeper idea than
it first appears, that you will need a bit of
time to settle into
What does Spring offer?
• Dependency Injection
– Also known as IoC (Inversion of Control)
• Aspect Oriented Programming
– Runtime injection-based
• Portable Service Abstractions
– The rest of spring
• ORM, DAO, Web MVC, Web, etc.
• Allows access to these without knowing how they
actually work
Dependency Injection defined
• Method to create needed dependencies or look
them up somehow without doing it in the
dependent code
– Often called Inversion of Control (IoC)
• IoC injects needed dependencies into the object
– Setters or Contructor
• Primary goal is reduction of dependencies in
– an excellent goal in any case
– This is the central part of Spring
What is a bean?
• Typical java bean with a unique id
• In spring there are basically two types
– Singleton
• One instance of the bean created and referenced
each time it is requested
– Prototype (non-singleton)
• New bean created each time
• Same as new ClassName()
• Beans are normally created by Spring as
late as possible
What is a bean definition?
• Defines a bean for Spring to manage
– Key attributes
class (required): fully qualified java class name
id: the unique identifier for this bean
configuration: (singleton, init-method, etc.)
constructor-arg: arguments to pass to the constructor at
creation time
• property: arguments to pass to the bean setters at creation
• Collaborators: other beans needed in this bean (a.k.a
dependencies), specified in property or constructor-arg
• Typically defined in an XML file
Sample bean definition
<bean id="exampleBean" class=”org.example.ExampleBean">
<property name="beanOne"><ref bean="anotherExampleBean"/></property>
<property name="beanTwo"><ref bean="yetAnotherBean"/></property>
<property name="integerProperty"><value>1</value></property>
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; }
Java Beans and Spring
• Beans have been with us since the beginning of Java
(1996 and beyond)
• Almost a non-concept – a bean is a simple Java object
with “getters and setters”
public class MyBean {
private String property;
public void setProperty(String property) { = property;
public String getProperty() {
return property;
• Spring concept of a bean is not very much more loaded –
however it is imagined that each bean “does some work”
• Setters in Spring are generally much more important
than getters
– used to deliver a dependency
A Simple Spring Bean
Setter method marks
this as a bean The dependency on
myService is
The bean’s business
method (work for its
clients) is defined
public class WorkerBean {
private UsefulService myService;
public void setMyService(UsefulService myService) {
this.myService = myService;
public int doMyWork(int argument) {
int result = myService.invoke(argument);
return result + 3;
• Notes:
– The whole point of Spring is not to see it
– Spring isn’t just about service location, but
it is one (common) way to use it
Spring Configuration for the bean
Injection here
delivers the bean
“myService” to the
setter on the client
<bean id=“usefulService” class=“mypackage.UsefulService”>
<bean class=“mypackage.WorkerBean”>
<property name=“myService” ref=“usefulService”/>
• Notes:
– The “id” attribute is optional, but typically supplied since you
usually want to refer to the bean again
– You can build a deeper and deeper tree of clients and
– The ultimate endpoint of a mature Spring design is to have the
entire application structure in Spring
• still a controversial view!
– The use of Spring in Sakai is typically much “thinner” – there is
ONE clear API/Impl boundary across the server
What is a bean factory?
• Often seen as an ApplicationContext
– BeanFactory is not used directly often
– ApplicationContext is a complete superset of bean
factory methods
• Same interface implemented
• Offers a richer set of features
• Spring uses a BeanFactory to create, manage
and locate “beans” which are basically instances
of a class
– Typical usage is an XML bean factory which allows
configuration via XML files
How are beans created?
Beans are created in order based on the dependency
Often they are created when the factory loads the definitions
Can override this behavior in bean
<bean class=“className” lazy-init=“true” />
You can also override this in the factory or context but this is
not recommended
Spring will instantiate beans in the order required by
their dependencies
1. app scope singleton - eagerly instantiated at container startup
2. lazy dependency - created when dependent bean created
3. VERY lazy dependency - created when accessed in code
How are beans injected?
• A dependency graph is constructed based
on the various bean definitions
• Beans are created using constructors
(mostly no-arg) or factory methods
• Dependencies that were not injected via
constructor are then injected using setters
• Any dependency that has not been
created is created as needed
Typical Spring usages
• The Spring configuration is typically written in
an XML file, defining an Application Context
– Recent support for configuration through Java 5
Annotations but this breaks the separation of
configuration and code (not recommended)
• Special support for loading in a Servlet
environment, creating a
WebApplicationContext from a file by default
named applicationContext.xml
– Initialised on context startup using Servlet
Listeners defined in web.xml
• Can also use Spring completely “headless”
by creating the application context by hand
Spring Web MVC
• Abstraction for the presentation technology you
want to use
– Some of the supported ones
• Fairly easy to use and popular for web
• RSF linkage in a minute
Why RSF?
• RSF was designed with several special
requirements of large scale development
communities in mind
– The first key point is to decouple the workflows of
developers and designers/UX experts, and allow
them to work independently
– The second key point is to enable universal
portability of apps to whatever environments may
arise, without requiring code changes (today, to
Servlets, Sakai, and JSR-168 Portlets, tomorrow to
JSR-286 or the final “containerless” liberation)
• RSF is closely involved with the FLUID “Flexible
UI” project now running out of UToronto
• Still an immature project
– Still in development
– 1.0 release maybe next year
• Not associated with any standard group
– Sun – NO
– Apache – Probably Not
– Spring – Maybe? (we hope)
RSF for coders and designers
• RSF is easy for coders since it is built out of
Spring components
– Developers can always break open the framework
in an emergency
– Once you get the pattern, it is really obvious how
to build very powerful components and apps that
require a lot more custom/stovepipe work in other
• RSF is easy for designers since they can just
work with plain HTML and hand it over the
fence to coders who can start working with it
Webapp Scopes
• There are basically 3 scopes that we
are concerned with in a webapp
– Application
– Session
– Request
Application Scope
• Beans/Objects in this scope are shared between
everything in the system
– 1 instance of items in this scope for your entire web
• Items here will tend to survive for as long as the
Servlet container
• Items here are accessible to anything in the
same Spring applicationContext
– For Sakai, this would mean anything in the
Component space
– Items often have an unlimited lifetime
– Items like this are typically used for managing access
to resources and performing functions which are
shared through the web app
• e.g. logic and dao beans
Session Scope
• Session typically refers to a user session (time between
login and logout) but it could be a tool session, user/tool
session, or other
• Beans/Objects in this scope are unique for each session
• As well as being a "cheap" kind of persistence, the
primary value of session beans lies in their being a kind
of ''authenticated storage''.
– These items are only accessible within the particular session,
and in general the infrastructure is set up around session state to
make it (very) hard in general for users to get access to each
others session state.
• Items have a limited lifetime but are long lived.
• Items like this are often used to maintain state in the
webapp for a workflow or for the entire session
– allows data to be stored without having to pass it between every
page but should be used only when necessary to avoid breaking
the standard statelessness of web applications
Request Scope
• Request typically refers to a single page or http request
• Bean/Objects in this scope are unique for each request
and will be created at the beginning of the request and
destroyed at the end
– Items are accessible for a very short time and only within this
– Items have a very limited lifespan which is typically fractions of a
• RSF encourages you to use request scope as opposed to
the session scope
– usually results in more usable and more efficient designs
• Many situations which in other frameworks require the use
of session beans are better handled by use of URL state
– ViewParameters in RSF
• Items like this are often used to process a request in some
– collecting submission data and processing navigation requests
Scopes illustrated
• This image shows the state of memory in a
container which is currently serving 3 web
requests (X, Y and Z), on behalf of two different
users/tools with sessions A and B.
– Note: access by multiple requests to the same session
(X, Y => A in this case) can cause problems in apps that
are not set up to deal with this, and is best prevented by
using the exclusive="true" annotation
RSF bean scopes
• RSF uses Spring to control the lifecycle of
various beans through a webapp created
using it
• You can inject any bean into any other
bean as long as the scope of the injected
bean is equal to or greater than the scope
of the receiving bean
• Consider that a bean at application scope can be identified uniquely
to a bean in session or request scope because there is only one in
the scope but going the other direction there could be multiple
session and requests so those beans cannot be identified uniquely.
Even if they could you would not want to try to use them because
the lifetimes are radically different!
RSF ApplicationContext
• RSF defines RSF related application
context (scoped) beans through the
applicationContext.xml file in the
tool/src/webapp/WEB-INF directory
• Most of these beans are used to configure
and control the RSF web app
– If you are using Sakai you will also likely have
a components.xml file which is used to define
things like logic and dao beans
RSF SessionContext
• Looking at using the Spring session
context in Spring 2.0.x
– Coming soon (we hope)
• Currently done using a bit of a hack with
the request scope in the
requestContext.xml file
– Reading values from the session scoped
beans can happen at any time
RSF RequestContext
• RSF defines request scoped beans in the
requestContext.xml file in the
tool/src/webapp/WEB-INF directory
• Processed using a very fast version of the
standard Spring AC called RSAC
• The values stored in request beans should
be set via RSF EL only. Do not set these
values by accessing the bean directly!
– Reading values from the request scoped
beans can only happen within the request
cycle (probably in the producer)
• Here is some real XHTML:
<head><title>RSF sample</title></head>
<h1>Hello <span rsf:id=“user-name”>User Name</span></h1>
Today is <span rsf:id=“current-date”>1/1/2006</span><br/>
<tr rsf:id=“item-row:”>
<td rsf:id=“item-value”>item value here</td>
• It is also an RSF template!
– To make a template, you simply add the rsf:id
attribute to tags which might have their content
replaced when the app runs, or might need to be
copied or moved about
RSF Templates
• The template will load and render fine in any
browser or editor
– Properly, we will always give RSF templates a proper
XHTML doctype, and namespace for the rsf:id attribute
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
<html xmlns:rsf="" xmlns="">
– The rsf:id attribute is the ONLY addition to the schema
– RSF can actually render with any kind of XML template,
not just XHTML
• Processed using the RSF IKAT renderer
Using the Template
• Everything in RSF is a Spring-configured
bean of some kind
• A special kind of bean called a Producer (or
View Producer) is responsible for rendering a
page from a template
– The same Producer can render from many
different templates, as long as the rsf:ids agree
• The purpose of a Producer is to create a
Component Tree of RSF “Primitive
Components” which will get paired up with
the template by the RSF renderer (IKAT)
View Producer
public class ItemsProducer implements ViewComponentProducer, DefaultView {
private CrudPlusLogic logic;
public void setLogic(CrudPlusLogic logic) {
this.logic = logic;
public void fillComponents(UIContainer tofill, ViewParameters viewparams,
ComponentChecker checker) {
UIOutput.make(tofill, "user-name", logic.getUserName());
for (CrudPlusItem item: logic.getAllVisibleItems().iterator()) {
UIBranchContainer itemrow =
UIBranchContainer.make(listform, "item-row:", item.getId());
UIOutput.make(itemrow, “item-value”, item.getValue());
UIOutput.make(itemrow, “current-date", new Date().toString() );
• Java code (a Spring bean) which defines what appears in the view
• UIOutput and UIBranchContainer are primitive RSF components
• The 2nd arguments to the make() calls match up with the rsf:ids
written in the template
RSF rendering basics
• UIOutput – will pair up with ANY tag in the
markup. The 3rd argument will replace the body of
the tag.
– rsf:id must not have a colon (e.g. “item-title”)
• UIBranchContainer – will also pair up with any
tag. Represents a “branch point” in the rendering
where a tag will be copied out again, missed out
completely, or rendered out of order.
– rsf:id must have a colon (e.g. “items-list:”)
• Full details on all the RSF primitive components
(like UILink, UIForm, UICommand) on the RSF wiki
Registering a Producer
• Spring beans typically live as long as the
entire application (application scope)
• RSF extends Spring with a fast request-scope
implementation called RSAC
• RSF Producers are typically declared as
Spring beans at request scope
• Request-scope beans go into
requestContext.xml rather than
applicationContext.xml, but the file format is
the same
• You can refer to any application-scope beans
(including Sakai services) directly as
dependencies of your request-scope beans
Example registration
• In WEB-INF/requestContext.xml:
<bean class="org.sakaiproject.crudplus.tool.producers.ItemsProducer">
<property name="logic"
ref="org.sakaiproject.crudplus.logic.CrudPlusLogic" />
• Typically no need for an id since RSF detects
and loads up producers by itself using Spring
• The one dependency in this example is a
bean representing a logic service at
application scope
RSF and Web MVC
• RSF works with Spring Web MVC
– A couple caveats
• You lose the nice URL abstraction provided by
RSF and have to manage your navigation yourself
• You also lose the nice widgets in RSF
– However
• You keep the IKAT pure XHTML rendering
– Will be working to better integrate this
• Currently working to integrate Spring Web
– Can replace the current flows in RSF
RSF and Portlets
• RSF apps can run as portlets
• Most of the changes to get this to work are
simply config files and jars which are
required for portlets
• In the ideal world, there would be a simple
maven build option to create a portlet or a
– Not there yet though
• RSF wiki, forums and JIRA
• Spring framework
• Demos
Размер файла
567 Кб
Пожаловаться на содержимое документа