Amazon Class Spring Beans

tenuousdrunkshipInternet και Εφαρμογές Web

12 Νοε 2013 (πριν από 3 χρόνια και 6 μήνες)

62 εμφανίσεις

Amazon Class Spring Beans


Reference :

file:///usr/local/lib/spring
-
framework
-
3.1.0.M1/docs/spring
-
framework
-
reference/html/beans.html




A
Java B
ean is just a Java class with no main method. There is a default constructor
and a set and get method for each public property.


Example of a Java Bean:


Class PoolBall


String name;




public PoolBall(){}



public void setName(String n){


t
his.name = n;


}




public String getName(){


return this.name


}






Aside:
The actual definition mentions the

class should be serializa
ble meaning you
have to implement the Serializable interface. Serialiazable

is an “Empty” interface
where you don’t have to implement any methods, you have to insure your class in
serializable. What this means is vague. Most of our classes by definition can be
serialized because
they inherit from Object, which
can be serialized.

When a class
contains parts which can’t be serialized
;

this is usually by design. Another way to
phrase this is we
can’t use transient

in Java Beans
. For example in some large
objects we store temp data which woul
d be too expensive to serialize both in te
rms
of time to serialize and disk space taken.
Like a class representing realtime data
str
eam from Nasdaq
.

We can store the object state representing the connection but
we wouldn’t store the data itself. It would take too much space or the time required
to

compress it wouldn’t be too high.
One

big deal with Java Beans

when created in
1998

was not the
requirement for a default zero argument default
ctor or the
public
property

and setter/getter methods but having the ability to

register event listeners
and having the Bean

distribute

events to other classes.
This event delegation
allowed Beans to be used first in GUI frameworks.
Part of
strategy behind the
Java
Bean effort was to make code reusable as we will see in the Spring fr
amework.
We
won’t cover EJBs in this class. It doesn’t make sense for Beans to exist by t
hemselves
despite predictions by

2000 people would be selling and buying beans in a
marketplace. They have to exist as par
t of a framework to be useful.


A Spring
Bea
n is a Java Bean managed by the

Spring framework with the runtime
managed by
the Spring IOC container. A Spring Bean is any class which is initialized
either in Spring or using a Spring XML configuration file. This can be a POJO,
JavaBean, EJB, anything Sp
ring can handle.


The advantage of Spring and using beans is in runtime man
agement. Spring
creates
references for

all

of the
application objects

into an
object graph before the
application starts up.

This does not mean the objects themselves are instantia
ted.

This is good because it makes the runtime object graph static and immutable.
This is
a big
advantage in trying to avoid un
reproduci
ble intermittent bugs.

This

design
technique is
useful in
scaling
Web MVC implementations.


An Application object is a

set of objects we use to define an application. If we built a
movie rental system we would create objects like Users, Movies, Shopping Cart, etc..
These high level objects are Application Objects. Data structures like a List<User>
are not considered Appli
cation Objects.


The creation of an immutable object graph is
one of
the fundamental concept
s

behind Spr
ing. To do this
,

Spring requires

you define all the dependencies
to other
objects using
references to other classes
.

Spring automates the construction of these
classes in it’s own runtime environment by defining a specific standard on how to
define constructors.

If you have a School Class then you set a List
<Students>
as a
private instance variable.
The Spring containe
r will create your Student object based
on the default no argument constructor then inject the Student dependency using
the setter method.






Image Source:
file:///usr/local/lib/spring
-
framework
-
3.1.0.M1/docs/spring
-
framework
-
reference/html/beans.html

Modify the image to add a graph of objects inside the green box.


In really
,

really old days we would take an application, create a data model,

try to
shove that into an Entity
-
Relation diagram which fit into a database then design the
application logic in a separate tier on top of that. That worked ok but was a mess
load of work.


W
e try to create an application object model of an applica
tion b
y mapping

the object
model into th
e database automatically and using a

combination of MVC

a
nd a 3 tier
model to implement the application.




This 3 tier partitioning allows us to scale into the cloud. We will cover both topics,
developing applications i
n Spring which is an interpretation of this 3 tier model then
we will add additional material to show how you can expand or replace the layers
with cloud services.


The Spring documentation recommends you use default ctors with setters for
injection. The
specification also supports constructor injection. Some like this
approach because it prevents the creation of partially initialized objects
.

http://blog.imaginea.com/spring
-
bean
-
creation
-
is
-
not
-
thread
-
safe/


To declare a Spring bean you can do this in code or in an XML file. The preferred
method is an XML file

named application
-
context.xml

to indicate you are putting
beans into an application context Spring container.

The Spring IOC container reads
this and creates Beans after reading the xml files.

Here some mulitiple styles for
creating beans you will see in different source examples:

<beans>


<bean name="foo" class="x.y.Foo">


<constructor
-
arg>



<bean class="x.y.Bar"/>


</constructor
-
arg>


<constructor
-
arg>


<bean class="x.y.Baz"/>


</constructor
-
arg>


</bean>

</beans>


<bean id=”messageSource”
class=”org.springframework
.context.support.ResourceBundleSo
ure”>

<property
name=”basename”><value>messages</value></property>

</bean>




Note in the above we can use ‘name’ or ‘id’ to specify the bean name/id.

<
bean

id
=
"exampleBean"

class
=
"examples.ExampleBean"
/>

<
bean

name
=
"
anotherExample"

class
=
"examples.ExampleBeanTwo"
/>



Note the different styles of bean specifications. There are many more.
The point is
there is a Spring vocabulary referring to classes

which you load into the runtime

as
beans and properties as initializa
tion
parameters.



Aside: Docs say you can do ctor injection and there are potential problems with
circular dependencies. There are runtime Exceptions generated from this.
Comment: In Spring Classes are singletons by default unless you add @Scope. We
aren
’t ginog to do this in the examples. Singletons are created at init of the IOC
conta
iner. This is relevant or impt to mention? Probably just distracts the student.


The Spring Container is called an
Application Context

and

is a
Resource Loader

which gives you access to resources(RHOK uses this), and gives you MessageSource
support. Implementations of ApplicationContext are
ClassPathXMLApplicationContext, FileSystemXMLContext,
XmlWebApplicationContext.



Resources allow you do to properties?


U
sing the p schema and properties to configure Beans:

http://developers
-
blog.org/blog/default/2010/02/17/DD1F42616D13DD5A6437E617805C613
5



Application Conte
xts
are important in Spring.
They are defined in
applicationContext.xml.
(reword RHOK leaves it open in RHOK)

Do we ne
ed Application Scopes?
Where is the scope defined???

A bean definition is used to create the object, a scope describes the lifetime of th
e
bean in the IOC container.

There are
5 bean scopes in Spring

1)

S
ingleton
: one bean defn to one object instance per Spring IOC container
. Use
for stateless beans.







<bean id="accountService"
class="com.foo.DefaultAccountService"/> <!
--

the
following
is equivalent, though redundant (singleton
scope is the default)
--
> <bean id="accountService"
class="com.foo.DefaultAccountService"
scope="singleton"/>


2)

P
rototype
: multiple instances per bean definition
.



<!
--

using spring
-
beans
-
2.0.dtd
--
> <bean
id="ac
countService"
class="com.foo.DefaultAccountService"
scope="prototype"/>



3)

request,
bean definition object lives for lifetime of HTTP Request. Each
HTTPRequest has it’s own copy of bean instance.
only available in
Applicati
i
on Context

Do we ne
ed to use the
se other scopes?


4)

session,

each session has bean object for HTTP Session

only available in
Application Context

and Spring Web Aware frameworks.



5)

global session,

bean object per Global HTTP Session. Used in Spring web
aware frameworks. O
nly available i
n Application Context



Spring Lab:
Create a Spring Bean and show you can write/read values to it.


Spring requires the creation of an application context before creating Spring

beans.
An Application Context is the object initializing the Spring Application Context
Container. Create the application context object first then you can retrieve the
Spring beans from the Object graph.



Create an Eclipse Dynamic Web Project



Create a we
b.x
ml using Deployment Descriptor>>Generate Deployment
Descriptor Stub
. This creates the web.xml file which initializes the Tomcat
Server. We will put the spring configuration into application
-
context.xml but
have to tell web.xml to scan for



Create application
-
context.xml under WebContent/META
-
INF using
New>>Other>>XML File>>(application
-
context.xml)



Download the spring libraries



Add
org.s
pring
framework.
core
-
3.1.0.M1.
jar to the build path



Add org.springframework.asm
-
3.1.0.M1.jar to the build
path



Add org.springframework.beans
-
3.1.0.M1.jar to the build path



Add org.springframework.context.support
-
3.1.0.M1.jar to the build path



Add org.springframework.context
-
3.1.0.M1.jar to the build path



Add org.springframework.expression
-
3.1.0.M1.jar to the b
uild path



Add org.springframework.framework.web
-
3.1.0.M1.jar to the build path



Eclipse>>Select Project>>Right Click Properties>>Deployment
Assembly>Add the jars in the build path to the Deployment Assembly.



Create a servlet and web.xml to make sure your p
roject setup is correct for a
servlet first

<servlet>


<
servlet
-
name
>
ScopeServlet
</
servlet
-
name
>


<
servlet
-
class
>
com.hackerdojo.ScopeServlet
</
servlet
-
class
>

</servlet>

<servlet
-
mapping>


<
servlet
-
name
>
ScopeServlet
</
servlet
-
name
>


<
url
-
pattern
>
/
ScopeServlet
</
url
-
pattern
>

</servlet
-
mapping>



package com.hackerdojo;


import java.io.IOException;


import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpSe
rvletRequest;

import javax.servlet.http.HttpServletResponse;


import org.springframework.context.ApplicationContext;


/**


* Servlet implementation class ScopeServlet


*/

@WebServlet("/ScopeServlet")

public class ScopeServlet extends HttpServlet {


private

static final long serialVersionUID = 1L;



/**



* @see HttpServlet#HttpServlet()



*/


public ScopeServlet() {



super();



// TODO Auto
-
generated constructor stub


}



/**



* @see HttpServlet#doGet(HttpServletRequest request,
HttpServletResponse



*

response)



*/


@Override


protected void doGet(HttpServletRequest request,




HttpServletResponse response) throws
ServletException, IOException {



// TODO

Auto
-
generated method stub



response.getWriter().write("<html><body>");



response.getWriter()
.write("<p>Test scope
examples</p>");



ApplicationContext ctx = AppContext.getCtx();







response.getWriter().write("display name:" +
ctx.getDisplayName());







response.getWriter().write("</body></html>");


}



/**



* @see HttpServlet#doPost(
HttpServletRequest
request, HttpServletResponse



* response)



*/


@Override


protected void doPost(HttpServletRequest request,




HttpServletResponse response) throws
ServletException, IOException {



// TODO Auto
-
generated method stub


}


}




Start
the servlet and make sure you get some text output on the browser to
verify the servlet is working before we startup the Spring Container



Modify web.xml to load an application
-
context.xml file. Convention is to
separate the application context from the web

server context. The
ContextLoaderListener allows us to scan for xml files and to automatically
add them. We specify the values to make sure we are being clear. Some
web.xml files will leave off the list of xml configuration files.

Modified web.xml file:

<web
-
app xmlns:xsi="http://www.w3.org/2001/XMLSchema
-
instance" xmlns="http://java.sun.com/xml/ns/javaee"

xmlns:web="http://java.sun.com/xml/ns/javaee/web
-
app_2_5.xsd"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web
-
app_3_0.xsd"
version="3.0">


<display
-
name>SpringScopeLectureExample</display
-
name>


<welcome
-
file
-
list>


<welcome
-
file>index.html</welcome
-
file>


<welcome
-
file>index.htm</welcome
-
file>


<welcome
-
file>index.
jsp</welcome
-
file>


<welcome
-
file>default.html</welcome
-
file>


<welcome
-
file>default.htm</welcome
-
file>


<welcome
-
file>default.jsp</welcome
-
file>


</welcome
-
file
-
list>




<servlet>



<servlet
-
name>ScopeServlet</servlet
-
name>



<servlet
-
class>
com.hackerdojo.ScopeServlet</servlet
-
class>


</servlet>


<servlet
-
mapping>


<servlet
-
name>ScopeServlet</servlet
-
name>


<url
-
pattern>/ScopeServlet</url
-
pattern>


</servlet
-
mapping>




<listener>


<listener
-
class>
org.springframework.web.context.ContextLoaderLis
tener</listener
-
class>


</listener>




<context
-
param>


<param
-
name>contextConfigLocation</param
-
name>


<param
-
value>



/META
-
INF/application
-
context.xml


</param
-
value>


</context
-
param>



</web
-
app>





Create an application
-
context.xml file under /META
-
INF. Some people put
this under /WEB
-
INF. Depends on your preference. Make sure you specify
the path to make your convention clear to readers of your code.

<?xml

version="1.0" encoding="UTF
-
8"?>

<beans xmlns="http://www.springframework.org/schema/beans"


xmlns:xsi="http://www.w3.org/2001/XMLSchema
-
instance"


xmlns:p="http://www.springframework.org/schema/p"


xsi:schemaLocation="http://www.springframework.org/sc
hema/
beans


http://www.springframework.org/schema/beans/spring
-
beans
-
3.1.xsd ">




<bean id="ApplicationContextProvider"
class="com.hackerdojo.ApplicationContextProvider"></bean>



</beans>




Create 2 Java Classes to represent the Application Context, an
ApplicationContextProvider and ApplicationContext Class.

package com.hackerdojo;


import org.springframework.context.ApplicationContext;

import
org.springframework.context.ApplicationContextAw
are;


public class ApplicationContextProvider implements
ApplicationContextAware {


@Override


public void setApplicationContext(ApplicationContext
ctx) {



AppContext.setCtx(ctx);


}

}



package com.hackerdojo;


import
org.springframework.context.ApplicationContext;


public class AppContext {


private static ApplicationContext ctx;



public static ApplicationContext getCtx() {



return ctx;


}



public static void setCtx(ApplicationContext ctx) {



AppContext.ctx = ctx;

}


}






Modify the ScopeServlet class to use the ApplicationContext and print out
something to show the user you have a valid Application Context




package com.hackerdojo;


import java.io.IOException;


import javax.servlet.ServletException;

import
javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import org.springframework.context.ApplicationContext;


/**


* Servlet implementation
class ScopeServlet


*/

@WebServlet("/ScopeServlet")

public class ScopeServlet extends HttpServlet {


private static final long serialVersionUID = 1L;



/**



* @see HttpServlet#HttpServlet()



*/


public ScopeServlet() {



super();



// TODO Auto
-
generated

constructor stub


}



/**



* @see HttpServlet#doGet(HttpServletRequest request,
HttpServletResponse



* response)



*/


@Override


protected void doGet(HttpServletRequest request,




HttpServletResponse response) throws
ServletException, IOException

{



// TODO Auto
-
generated method stub



response.getWriter().write("<html><body>");



response.getWriter().write("<p>Test scope
examples</p>");



ApplicationContext ctx = AppContext.getCtx();







response.getWriter().write("display name:" +
ctx.getDisp
layName());







response.getWriter().write("</body></html>");


}



/**



* @see HttpServlet#doPost(HttpServletRequest
request, HttpServletResponse



* response)



*/


@Override


protected void doPost(HttpServletRequest request,




HttpServletResponse response) throws
ServletException, IOException {



// TODO Auto
-
generated method stub


}


}







Run the Servlet you should see this:







Create a Java Class called Movie, add an attribute Name, Title, and a List of
Actors. Use Eclipse
>>Source>>Generate Getters and Setters to add the
setters and getters automatically, add a default constructor. Add the bean
id/class mappings to application
-
context.xml. Modify the ScopeServlet.java
file to set and display a property and print it out on t
he HTML page. Note
how fast we can add classes to the Spring framework. We have a web server
up and running. We type in a new class with properties. We autogenerate the
methods. We add in a single line for configuration into the application
-
context.xml fi
le and we can use the object in the runtime without having to
call the constructor new Movie(). NO more factory classes, no more hunting
down when other programmers created objects


Movie Class:


package com.hackerdojo;


import java.util.List;

public

class Movie {





private String title;


private String year;


private List<String> actors;



public Movie() {


}



public String getTitle() {



return title;


}



public void setTitle(String title) {



this.title = title;


}



public String getYear() {



return year;


}



public void setYear(String year) {



this.year = year;


}



public List<String> getActors() {



return actors;


}



public void setActors(List<String> actors) {



this.actors = actors;


}


}


Modified application
-
context.xml file:


<?xml

version="1.0" encoding="UTF
-
8"?>

<beans
xmlns="http://www.springframework.org/schema/beans"


xmlns:xsi="http://www.w3.org/2001/XMLSchema
-
instance"


xmlns:p="http://www.springframework.org/schema/p"


xsi:schemaLocation="http://www.springframework.org/sc
hema/beans


http://www.springframework.org/schema/beans/spring
-
beans
-
3.1.xsd ">




<bean id="ApplicationContextProvider"
class="com.hackerdojo.ApplicationContextProvider"></be
an>


<bean id="Movie" class="com.hackerdojo.Movie"></bean>

</beans>



Modifi
ed ScopeServlet.java File:

package com.hackerdojo;


import java.io.IOException;


import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import
javax.servlet.http.HttpServletResponse;


import org.springframework.context.ApplicationContext;


/**


* Servlet implementation class ScopeServlet


*/

@WebServlet("/ScopeServlet")

public class ScopeServlet extends HttpServlet {


private static final long se
rialVersionUID = 1L;



/**



* @see HttpServlet#HttpServlet()



*/


public ScopeServlet() {



super();



// TODO Auto
-
generated constructor stub


}



/**



* @see HttpServlet#doGet(HttpServletRequest request,
HttpServletResponse



* response)



*/


@Override


protected void doGet(HttpServletRequest request,




HttpServletResponse response) throws
ServletException, IOException {



// TODO Auto
-
generated method stub



response.getWriter().write("<html><body>");



response.getWriter().write("<p>Test sco
pe
examples</p>");



ApplicationContext ctx = AppContext.getCtx();



response.getWriter().write("display name:" +
ctx.getDisplayName());



Movie movie = (Movie) ctx.getBean("Movie");



movie.setTitle("This is a movie title");



response.getWriter().write("
display movie
title:" + movie.getTitle());




response.getWriter().write("</body></html>");


}



/**



* @see HttpServlet#doPost(HttpServletRequest
request, HttpServletResponse



* response)



*/


@Override


protected void doPost(HttpServletRequest

request,




HttpServletResponse response) throws
ServletException, IOException {



// TODO Auto
-
generated method stub


}


}




Web Page:
http://localhost:8080/SpringScopeLectureE
xample/ScopeServlet






So far we have only initialized properties which contain a single
reference to a primitive type. How do you initialize data structures?

T
he line

in our application
-
context.xml header
:
xmlns:p="http://www
.springframework.org/schema/p"
is

called a “p
schema


and defines a separate namespace.

We use this to initialize our List
data structure.

The

Sun Java Bean documentation refers to private instance
variables of classes as properties. Spring refers to argu
ments in constructors
as properties and when using setter/getter methods to set class variables as
setting “properties” of a class.


Spring
converts the string in property names into the java.util.properties
class.
You can access this and test??


<
property name="driverClassName"
value="com.mysql.jdbc.Driver"/>


Spring converts the text inside <value> to a java.util.Properties instance
using the JavaBeans PropertyEditor mechanism.

WTF??


The Spring container converts the text inside the
<value/>

ele
ment into a
java.util.Properties

instance by using the JavaBeans
PropertyEditor

mechanism. This is a nice shortcut, and is one of a few places where the
Spring team do favor the use of the nested
<value/>

element over the
value

attribute style.


<bean id="
Movie" class="com.hackerdojo.Movie">



<property name="actors">




<list>





<value>ASDF</value>





<bean
class="java.lang.String"><constructor
-
arg value= "1"
/></bean>





<null />




</list>



</property>



</bean>


Print out the value of the
list:













i