Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
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