1 / 79

Training - Day 4

Training - Day 4. The Spring Framework & Testing Web Applications. “Spring's main aim is to make J2EE easier to use and promote good programming practice. It does this by enabling a POJO-based programming model that is applicable in a wide range of environments.”

teague
Download Presentation

Training - Day 4

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Training - Day 4 The Spring Framework & Testing Web Applications

  2. “Spring's main aim is to make J2EE easier to use and promote good programming practice. It does this by enabling a POJO-based programming model that is applicable in a wide range of environments.” - Rod Johnson What does Spring do?

  3. No logging API No connection pools No O/R mapping layer It does not reinvent the wheel. There are great projects that solve these problems and Spring’s goal is to make them easy to use. What it does not do

  4. Inversion of Control Spring’s bean factory, which allows objects to be retrieved by name Singleton – one shared object in the factory (Default) Prototype – the factory will always create a new object Dependency Injection… a better name. “Don’t call me, I’ll call you!” Takes the responsibility of making things happen away from the application code and moves it into the framework Spring is an IoC Container

  5. No Spring API intrusion in your code if you don’t want it Objects, or dependencies, are injected using ordinary Java method calls Configured in XML and injected at runtime Dependency Injection

  6. Setter Injection Uses JavaBean setter methods Probably used more often Constructor Injection Uses constructor arguments Useful in special cases where objects need to do work in constructors Both types can be mixed Types of Dependency Injection

  7. Developers don’t have to worry about looking dependencies up…such as JNDI in EJB projects. Easier to test. Simple JavaBean setters are easier to mock than a JNDI service. Promotes strong typing. What are the benefits?

  8. Dependencies are explicit in the configuration… no need to read the code to determine application configuration. Easy to integrate legacy code because Spring Dependency Injection works with POJO (because of the two types of injection) – so it’s not intrusive. Benefits continued…

  9. Different ways to use Spring Can be a full fledged application Can be used modularly Major Pieces Core Context DAO & ORM AOP Web & Web MVC Use as much of Spring as needed

  10. Provides the Dependency Injection functionality which allows configuration and management of your bean container. This is the BeanFactory No more need for programmatic singletons Decouples configuration and the specification of dependencies in code Core

  11. Provides access to beans in a framework-style manner ApplicationContext JNDI / EJB Support Remoting Etc. Context

  12. DAO Programmatic and Declarative transaction management of any object (POJO) JDBC abstraction: vendor error codes, etc. ORM Provides integration for popular O/R mapping frameworks like OJB and Hibernate. Lots of hooks to take advantage of, for example, the declarative transaction management. DAO and ORM

  13. Aspect Oriented Programming AOP Alliance Compliant implementation of AOP. Provides method interceptors and pointcuts to cleanly separate code. AOP

  14. Web Web oriented application contexts. Initialization via servlet listeners. Multipart functionality. Web MVC Spring’s version of Struts. Web and Web MVC

  15. Typical UIS Spring Usage Scenario Spring middle-tier using a third-party web framework Note: We will use OJB rather than Hibernate.

  16. An ApplicationContext is a BeanFactory, and will be used most, if not all, of the time in UIS applications. ApplicationContext adds capabilities to the BeanFactory, most notibly J2EE specific functionality. You will need default empty constructors for setter injection. BeanFactory & ApplicationContext

  17. Programmatic Instantiation of an Application Context BeanFactoryLocator bfLocator = SingletonBeanFactoryLocator.getInstance("Spring.xml"); BeanFactoryReference bfReference = bfLocator.useBeanFactory("appContext"); BeanFactory factory = bfReference.getFactory(); ApplicationContext appContext = (ApplicationContext) factory; Spring.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="appContext" class="org.springframework.context.support.ClassPathXmlApplicationContext"> <constructor-arg> <list> <value>SpringDataSource.xml</value> <value>SpringBeans.xml</value> </list> </constructor-arg> </bean> </beans> Example

  18. Partial Contents of SpringBeans.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!-- User Service --> <bean id="trnUserService" class="edu.iu.uis.train.service.UserServiceImpl"> <property name="userDAO" ref="trnUserDAO" /> </bean> <!-- User DAO --> <bean id="trnUserDAO" class="edu.iu.uis.train.dao.UserDAOOjbImpl"> <property name="jcdAlias" value="MYDB"/> </bean> </beans> Example continued…

  19. A class name An id or name Singleton or prototype Bean properties Autowiring Lifecycle methods Defining a <bean/>

  20. class=“package.classname” Most likely, the name of the actual implementing class of the object. The preceding example Can also be the Factory that creates the object (this is a more rare case). A few examples follow Class Name

  21. <bean id="exampleBean" class="examples.ExampleBean2" factory-method="createInstance"/> or… <bean id="myFactoryBean" class="...“/> <bean id="exampleBean" factory-bean="myFactoryBean" factory-method="createInstance"/> Factory examples

  22. id=“beanName” or name=“beanName” The id attribute is limited to the characters in a valid XML id If you need special characters, or want multiple ids, or aliases, you can use the name attribute (comma or semicolon separates multiple). Id and Name

  23. singleton=“[true|false]” Singleton will use one shared instance of the bean for all requests (Default). Prototype will result in the creation of a new bean for each request. This is not used very often. Spring does not handle the lifecycle of prototype bean as it does singletons. Singleton or Prototype?

  24. Setter-injection Recommended approach as constructor arguments can become unwieldy Decouples code and enforces true JavaBeans Constructor-injection Many ways to configure. Ensures beans are created in a valid state. Ensures beans have values if needed at object creation. Bean Properties

  25. <bean id="exampleBean" class="examples.ExampleBean"> <property name="beanOne"> <ref bean="anotherExampleBean"/> </property> <property name="beanTwo"> <ref bean="yetAnotherBean"/> </property> <property name="integerProperty"> <value>1</value> </property> </bean> <bean id="anotherExampleBean" class="examples.AnotherBean"/> <bean id="yetAnotherBean" class="examples.YetAnotherBean"/> Setter Properties Example

  26. 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; } } Example continued…

  27. <bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg> <ref bean="anotherExampleBean"/> </constructor-arg> <constructor-arg> <ref bean="yetAnotherBean"/> </constructor-arg> <constructor-arg type="int"> <value>1</value> </constructor-arg> </bean> <bean id="anotherExampleBean" class="examples.AnotherBean"/> <bean id="yetAnotherBean" class="examples.YetAnotherBean"/> Constructor Example

  28. public class ExampleBean { private AnotherBean beanOne; private YetAnotherBean beanTwo; private int i; public ExampleBean(AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) { this.beanOne = anotherBean; this.beanTwo = yetAnotherBean; this.i = i; } } Example continued…

  29. <bean id="exampleBean" class="examples.ExampleBean" factory-method="createInstance"> <constructor-arg> <ref bean="anotherExampleBean"/> </constructor-arg> <constructor-arg> <ref bean="yetAnotherBean"/> </constructor-arg> <constructor-arg> <value>1</value> </constructor-arg> </bean> <bean id="anotherExampleBean" class="examples.AnotherBean"/> <bean id="yetAnotherBean" class="examples.YetAnotherBean"/> Factory/Constructor Example

  30. public class ExampleBean { // a private constructor private ExampleBean(...) { ... } // a static factory method // the arguments to this method can be considered // the dependencies of the bean that is returned, // regardless of how those arguments are actually used. public static ExampleBean createInstance( AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) { ExampleBean example = new ExampleBean(...); // some other operations return example; } } Example continued…

  31. Happens by argument type. If no ambiguity, Spring can resolve for you via type matching (as in previous example). Otherwise, you can use argument indexing. Constructor Argument Resolution

  32. <bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg index="0"> <value>7500000</value> </constructor-arg> <constructor-arg index="1"> <value>42</value> </constructor-arg> </bean> Argument Indexing Example

  33. <value>…</value> Used to set a textual value Can be used for int, boolean, and String <null/> Lists, sets, maps and props Allows for their equivalent data types to be used. More on property “values”

  34. <bean id="moreComplexObject" class="example.ComplexObject"> <!-- results in a setPeople(java.util.Properties) call --> <property name="people"> <props> <prop key="HarryPotter">The magic property</prop> <prop key="JerrySeinfeld">The funny property</prop> </props> </property> <!-- results in a setSomeList(java.util.List) call --> <property name="someList"> <list> <value>a list element followed by a reference</value> <ref bean="myDataSource"/> </list> </property> <!-- results in a setSomeMap(java.util.Map) call --> <property name="someMap"> <map> <entry> <key><value>yup an entry</value></key> <value>just some string</value> </entry> </map> </property> <!-- results in a setSomeSet(java.util.Set) call --> <property name="someSet"> <set> <value>just some string</value> <ref bean="myDataSource"/> </set> </property> </bean> A few more examples…

  35. <idref bean=“…”/> Same a id Benefit is that Spring can validate it. <idref local=“…”/> When bean is in the same XML config file. Similar to above, but the XML parser can validate at document parse time. <idref> Attribute

  36. Allows a property to use another bean reference as its value <ref bean="someBean"/> Can also take advantage of local Shortcuts <property name="myProperty" value="hello"/> <constructor-arg value="hello"/> <entry key="myKey" value="hello"/> <ref> Attribute

  37. Create a movie DAO bean in the SpringBeans.xml file and inject it into the movie service. Exercise: Bean wiring

  38. Spring Magic! Spring will try to figure out what dependencies should be injected into your beans. Can not have ambiguities. Not recommended. Autowiring

  39. < bean … init-method=“…”/> Specifies a method to call after a bean is created. <bean … destroy-method=“…”/> Specifies a method to call after a bean is about to be destroyed (a callback). Lifecycle Attributes

  40. More framework oriented Recommended over a plain Bean Factory Provides: Access to I18N style messages Access to resources Event propagation Loading of multiple contexts The Application Context

  41. Add a listener to web.xml to start Spring <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> The listener can be configured with a context parameter <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/classes/SpringBeans.xml /WEB-INF/classes/SpringDataSource.xml </param-value> </context-param> Creating an Application Context

  42. In your struts-config.xml <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"/> You also need to define your Action injection in /WEB-INF/action-servlet.xml <beans> <bean name="/BanUser" class="edu.iu.uis.train.web.BanUserAction"> <property name="userService" ref="trnUserService" /> </bean> <bean name="/Admin" class="edu.iu.uis.train.web.AdminAction"> <property name="userService" ref="trnUserService" /> </bean> </beans> Injecting your Struts Actions

  43. - Finally, delegate Struts actions to Spring proxies <action path=”/Admin" type="org.springframework.web.struts.DelegatingActionProxy" name=”AdminForm" parameter="methodToCall"> <forward name="success" path="/WEB-INF/jsp/admin/Admin.jsp" /> </action> Injecting Actions Continued…

  44. Modify struts-config.xml to use Spring Update action-servlet.xml with proper classes and injected services. Exercise: Injecting Struts

  45. Another approach to obtaining spring services in Actions or other services Allows “singleton-like” access to services by a constant name Calls the BeanFactory to retrieve the bean behind the scenes Couples code a bit more than injection, but is sometimes easier to use Need to keep the constants up to date in the locator class file Need to recompile code when additions are needed A Spring Service Locator

  46. public class SpringServiceLocator { private static ApplicationContext appContext; private static boolean initializationBegan = false; public static final String USER_SRV = "trnUserService"; public static final String PROJECT_SRV = "trnProjectService"; public static Object getService(String serviceName) { if (appContext == null && !initializationBegan) { initializationBegan = true; initializeAppContexts("Spring.xml"); } else if (appContext == null && initializationBegan) { throw new RuntimeException("Spring not initialized properly."); } return appContext.getBean(serviceName); } protected static void initializeAppContexts(String rootContextFile) { BeanFactoryLocator bfLocator = SingletonBeanFactoryLocator.getInstance(rootContextFile); BeanFactoryReference bfReference = bfLocator.useBeanFactory("appContext"); BeanFactory factory = bfReference.getFactory(); appContext = (ApplicationContext) factory; } Example

  47. public static UserService getUserService() { return (UserService) getService(USER_SRV); } public static ProjectService getProjectService() { return (ProjectService) getService(PROJECT_SRV); } public static void setAppContext(ApplicationContext newAppContext) { appContext = newAppContext; } public static ApplicationContext getAppContext() { return appContext; } public static void close() { if (appContext instanceof ConfigurableApplicationContext) { ((ConfigurableApplicationContext) appContext).close(); } } } Example continued…

  48. User user = SpringServiceLocator.getUserService(). findUserByUsername(role.getUser().getUsername()); As opposed to… User user = getUserService().findUserByUsername( role.getUser().getUsername()); Using the locator

  49. Aspect Oriented Programming compliments OOP. Breaks programs down into aspects and concerns, often times called cross-cutting concerns. In Spring, AOP is used for: Declarative enterprise services Implementing custom aspects You choose how much AOP you want to use Spring AOP

  50. AOP terminology is confusing and unintuitive. The Spring Framework did not want to change this terminology, which could have made it more confusing, but rather stuck with the generic AOP terms. AOP Concepts

More Related