Download Amazon Class Spring Beans

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Amazon Class Spring Beans
Reference : file:///usr/local/lib/spring-framework-3.1.0.M1/docs/springframework-reference/html/beans.html
A Java Bean 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){
this.name = n;
}
public String getName(){
return this.name
}
Aside: The actual definition mentions the class should be serializable 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 would be too expensive to serialize both in terms
of time to serialize and disk space taken. Like a class representing realtime data
stream 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 framework. We
won’t cover EJBs in this class. It doesn’t make sense for Beans to exist by themselves
despite predictions by 2000 people would be selling and buying beans in a
marketplace. They have to exist as part of a framework to be useful.
A Spring Bean 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 Spring can handle.
The advantage of Spring and using beans is in runtime management. 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 instantiated.
This is good because it makes the runtime object graph static and immutable. This is
a big advantage in trying to avoid unreproducible 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 Application Objects.
The creation of an immutable object graph is one of the fundamental concepts
behind Spring. 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 container 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/springframework-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.
We try to create an application object model of an application by mapping the object
model into the database automatically and using a combination of MVC and 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 in 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 initialization 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
container. 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?
Using the p schema and properties to configure Beans:
http://developersblog.org/blog/default/2010/02/17/DD1F42616D13DD5A6437E617805C613
5
Application Contexts are important in Spring. They are defined in
applicationContext.xml. (reword RHOK leaves it open in RHOK)
Do we need Application Scopes? Where is the scope defined???
A bean definition is used to create the object, a scope describes the lifetime of the
bean in the IOC container.
There are 5 bean scopes in Spring
1) Singleton: 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) Prototype: multiple instances per bean definition.
<!-- using spring-beans-2.0.dtd --> <bean
id="accountService"
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
Applicatiion Context
Do we need to use these 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. Only available in 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 web.xml 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.springframework.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 build 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 project setup is correct for a
servlet first
<servlet>
<servlet-name>ScopeServlet</servlet-name>
<servlet-class>com.hackerdojo.ScopeServlet</servletclass>
</servlet>
<servlet-mapping>
<servlet-name>ScopeServlet</servlet-name>
<url-pattern>/ScopeServlet</url-pattern>
</servlet-mapping>
package com.hackerdojo;
import java.io.IOException;
import
import
import
import
import
javax.servlet.ServletException;
javax.servlet.annotation.WebServlet;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
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/XMLSchemainstance" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/webapp_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</displayname>
<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>
<servletclass>com.hackerdojo.ScopeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ScopeServlet</servlet-name>
<url-pattern>/ScopeServlet</url-pattern>
</servlet-mapping>
<listener>
<listenerclass>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/schema/
beans
http://www.springframework.org/schema/beans/springbeans-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.ApplicationContextAware;
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
import
import
import
import
javax.servlet.ServletException;
javax.servlet.annotation.WebServlet;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
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
}
}

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 the 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 applicationcontext.xml file 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/springbeans-3.1.xsd ">
<bean id="ApplicationContextProvider"
class="com.hackerdojo.ApplicationContextProvider"></be
an>
<bean id="Movie" class="com.hackerdojo.Movie"></bean>
</beans>
Modified ScopeServlet.java File:
package com.hackerdojo;
import java.io.IOException;
import
import
import
import
import
javax.servlet.ServletException;
javax.servlet.annotation.WebServlet;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
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());
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/SpringScopeLectureExample/ScopeServlet
So far we have only initialized properties which contain a single
reference to a primitive type. How do you initialize data structures?
The 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 arguments 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/> element 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