1.13k likes | 1.38k Views
Spring/Testing Training. Jay Sissom. Topics. Java Interfaces Service Oriented Architecture Spring Testing with junit. Exercise 1. Check out FPS/TRAINING/INTERFACE1 Open edu.iu.uis.Main.java Create instances for each pet Put them all in a collection
E N D
Spring/Testing Training Jay Sissom
Topics • Java Interfaces • Service Oriented Architecture • Spring • Testing with junit
Exercise 1 • Check out FPS/TRAINING/INTERFACE1 • Open edu.iu.uis.Main.java • Create instances for each pet • Put them all in a collection • Iterate through the collection and print each pet’s name and make it speak (Don’t modify Cat & Dog classes) • Hint: instanceof
Java Interface • An Interface is a special Java class that defines behavior but doesn’t implement the behavior • It defines what another object will do, not how it does it • It is used to declare methods that an object must implement • Use of interfaces allows objects to be dependant on behavior, but not specific object instances
Java Interface • By using Interfaces, you don’t hard code which object must provide a service for you • The object providing the service can be any object that implements the required interface
Java Interface • An example is Collection. A Collection must allow you to: • Add items • Clear all items • Remove items • Get the size • Get an iterator to all members • (among other things) • http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collection.html
Java Interface • Many objects implement the Collection interface • ArrayList • Vector • LinkedList • And the list goes on…. • http://java.sun.com/j2se/1.4.2/docs/api/java/util/LinkedList.html
Java Interface • You can create your own Java interface: public interface Worker { public Collection getData(); public void doWork(); }
Java Interface • Any number of classes can implement your interface: public class MyWork implements Worker { public Collection getData() { return new ArrayList(); } public void doWork() { // Pretend I’m working } }
Java Interface • Your interface can be used in place of an object name: public Worker getMyWorker() … public void doStuff(Worker w) … • When doing this, your code isn’t dependent on a single implementation of Worker. Any implementation will do.
Exercise 2 • Use interface1 project (or check out FPS/TRAINING/INTERFACE1ANSWER if you didn’t finish Exercise 1) • Create a Pet interface that defines the common functionality in Cat & Dog • Change Cat & Dog to implement this interface • Change Main to use the interface instead of specific instances • Extra Credit: Add a Parrot object and use it
Animal public String speak(); public String getName(); Dog Inheritance • Inheritance is a parent child relationship between classes • Children inherit a parent’s functionality
Inheritance • Inheritence implies that all children will have the functionality defined in the parent • You have to be very careful when designing inheritance Animal public String speak(); public String getName(); DonGrinstead Ant
Solution with Interfaces • Using interfaces in this case would be more accurate Speaker <<interface>> public String speak(); Named <<interface>> public String getName(); DonGrinstead Ant
Interface Conclusion • A Java Interface defines what implementing objects do, not how they do it • Using interfaces will decouple your code from dependant objects. This will make it easier to maintain the code in the future
Exercise 3 • Check out FPS/TRAINING/INTERFACE3 • Create an implementation of OrderCalculator that calculates sales tax as 6% if from Indiana, 0 if from another state • Shipping is $20 if another state, $15 if Indiana • Change Main to use this interface • Modify the interface to add this method: public double getOrderTotal(Order o); that returns the total of the order with tax & shipping • Modify Main to use this method • Make sure you modify both implementations to implement this interface
Interfaces Pt 2 • We still had to put the name of the implementation class in our last example • If we used that throughout our application, we’d need to change it everywhere • This is still a problem
Interfaces Pt 2 • A solution is to create a new class that has a method to return the implementation we want • public OrderCalculator getInstance(); • This allows us to specify our implementation once for the whole app • This is called the Factory pattern
Exercise 4 • Use interface3 project • Create OrderCalculatorFactory class that has one method public OrderCalculator getInstance(); • This method should return an instance of your order calculator class • Change Main to use the factory
Interfaces Pt 3 • Now we specified the implementation class in one place in our app • This is better, but it would be best if the implementation class name wasn’t in Java code • We can put this class name in a properties file. The factory can read the properties file to determine the class name • Now the class name isn’t in compiled Java code. See FPS/TRAINING/INTERFACE4ANSWER2 for an example
Interfaces Pt 3 • Now we need a Factory, Interface and properties file for each class • This is too much work! • We could build a Factory framework so we need one factory and properties file for our app • Or we could use an open source framework called Spring
Spring • Spring Mission Statement • J2EE should be easier to use • It's best to program to interfaces, rather than classes. Spring reduces the complexity cost of using interfaces to zero. • JavaBeans offer a great way of configuring applications. • OO design is more important than any implementation technology, such as J2EE. • Checked exceptions are overused in Java. A framework shouldn't force you to catch exceptions you're unlikely to be able to recover from. • Testability is essential, and a framework such as Spring should help make your code easier to test.
Spring • Spring can replace our factory classes and properties file • All classes can be defined to spring and we don’t need to write custom factories • See FPS/TRAINING/SPRING1ANSWER
Spring • Objects are defined as “beans” in a spring xml file: <beanid="OrderCalculator"class="edu.iu.uis.NewOrderCalculator"/> • The object is accessed via the beanFactory: OrderCalculator oc = (OrderCalculator)factory.getBean("OrderCalculator");
Execise 5 • Check out FPS/TRAINING/SPRING2 • Refactor NewOrderCalculator to use MemorySalesTax object • Use Spring as the factory to find the object (the beanFactory is provided for you)
Dependencies • OrderCalculator depends on the SalesTax object to do its work • Main depends on OrderCalculator • When an object needs another to do its work, that is a Dependency • Spring helps satisfy dependencies • Using Interfaces makes it flexible
Dependencies • To satisfy dependencies in our code we can: • Create the dependent objects using new • Use a Factory to get them • Have something external to the object create them for us • The last option is called Dependency Injection or Inversion of Control
Inversion of Control • There are three types of IoC • Constructor Based • Setter Based • Getter Based
Constructor Based IoC • All dependent objects are passed on the constructor • All dependancies are satisfied when the object is created • If you have lots of dependancies, you have a huge constructor
Setter Based IoC • All dependent objects have a setXXX method • The factory will call these for each dependent object • Good when there are lots of dependencies • This documents the dependencies better than Constructor based IoC
Getter Based IoC • Each object needs access to a container • The object calls get methods on the container to get dependencies • This is the way we have been using Spring • Our code now has a dependency on Spring which may be a problem
Spring IoC • Spring supports all three IoC types • Getter - using BeanFactory • Setter - using bean.xml • Constructor - using bean.xml • The most popular is Setter based IoC • This is the recommended way to handle dependencies
Spring Setter IoC • Dependencies are mapped in the bean xml file • Update the xml to show the dependency • Create a setter method in the bean • The setter method saves the dependency to use it in the future
Spring Setter IoC • Update the xml to show the dependency <beanid="OrderCalculator"class="edu.iu.uis.NewOrderCalculator"> <propertyname="salesTax"> <refbean="SalesTax"/> </property> </bean>
Spring Setter IoC • Create a setter method in the bean & save the dependency to use when necessary private SalesTax salesTax; public void setSalesTax(SalesTax st) { salesTax = st; }
Exercise 6 • Modify the spring2 project to use setter injection in OrderCalculator • Hint: You can remove the BeanFactory code in NewOrderCalculator because it isn’t necessary anymore FPS/TRAINING/SPRING2ANSWER2
Spring with Struts • There are a few steps required to get Spring working with Struts • Starting up Spring • Location of bean xml • Spring/Struts integration
Starting up Spring • Spring starts up with a servlet listener • This code needs to be in web.xml <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
Location of bean xml • Spring looks for beans in /WEB-INF/applicationContext.xml • This can be changed by adding the following in web.xml <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/daoContext.xml /WEB-INF/applicationContext.xml</param-value> </context-param>
Spring/Struts integration • Spring can handle IoC in Struts Actions • Define dependencies in xml file • Spring calls setter methods in Struts Actions
Spring/Struts integration • Define Struts plugin in struts-config.xml <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"/> • Spring looks in /WEB-INF/action-servlet.xml for Struts action bean definitions • Note: action is the name of the Struts Servlet in web.xml
Spring/Struts integration • The type of each action in struts-config.xml should be org.springframework.web.struts.DelegatingActionProxy • The dependencies and actual type should be defined in action-servlet.xml <bean name="/path" class="edu.iu.uis.pdp.action.ChannelAction"> <property name="userService"><ref bean="pdpUserService"/></property> </bean> • Note: /path needs to match path in <action-mappings> in struts-config.xml
Spring/Struts integration • Struts Actions are defined in action-servlet.xml • Other beans are defined in applicationContext.xml • Struts actions can access beans defined in applicationContext.xml • applicationContext.xml beans can’t access Struts actions
Exercise 7 • Check out FPS/TRAINING/STRUTS1 • Setup Spring for the application • Put beans in applicationContext.xml & action-servlet.xml • Put setter methods in beans • Update struts-config.xml for Spring • Update web.xml for Spring
Application Testing • Unit Testing – Test each object as it is written • Functional Testing – Test each use case to make sure it works properly • Usability Testing – Test the app to make sure users understand it • Load Testing – Make sure the application will perform properly under a load
jUnit • Unit Tests are a series of tests that verify each component of your application • jUnit is a framework to help standardize these tests • jUnit can help automate tests so it is easy to see if a component works • Open Source Framework • Integrated into Eclipse and ant
Why Unit Test? • Find bugs soon after code is written • Save other team members’ time • Prove that finished code works • Make future maintenance easier • Example of how to use code
Unit testing goals • Each class has tests for all public methods • Tests not only test successes, but also test failures • Tests are organized so they are easy to run • Tests are run often • Each test is completely independent of other tests • Each time a bug is found, write an additional test to check for that bug, then fix the bug
jUnit Concepts • TestCase – a series of related tests • All the tests for an object • All the tests for a method • TestSuite – a series of related test cases • All tests for a package • All tests for a use case • All tests for an application