Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "Training - Day 4 The Spring Framework & Testing Web Applications."— Presentation transcript:

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

2 What does Spring do? “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

3 What it does not do 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.

4 Spring is an IoC Container 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

5 Dependency Injection 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

6 Types of Dependency Injection 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

7 What are the benefits? 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.

8 Benefits continued… 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.

9 Use as much of Spring as needed 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

10 Core 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

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

12 DAO and ORM 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.

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

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

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

16 BeanFactory & ApplicationContext 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.

17 Example 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 SpringDataSource.xml SpringBeans.xml

18 Example continued… Partial Contents of SpringBeans.xml

19 Defining a A class name An id or name Singleton or prototype Bean properties Autowiring Lifecycle methods

20 Class Name 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

21 Factory examples or…

22 Id and Name 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).

23 Singleton or Prototype? 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.

24 Bean Properties 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.

25 Setter Properties Example 1

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

27 Constructor Example 1

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

29 Factory/Constructor Example 1

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

31 Constructor Argument Resolution 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.

32 Argument Indexing Example 7500000 42

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

34 A few more examples… The magic property The funny property a list element followed by a reference yup an entry just some string just some string

35 Attribute –Same a id –Benefit is that Spring can validate it. –When bean is in the same XML config file. –Similar to above, but the XML parser can validate at document parse time.

36 Attribute Allows a property to use another bean reference as its value – Can also take advantage of local Shortcuts –

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

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

39 Lifecycle Attributes –Specifies a method to call after a bean is created. –Specifies a method to call after a bean is about to be destroyed (a callback).

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

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

42 Injecting your Struts Actions In your struts-config.xml You also need to define your Action injection in /WEB-INF/action- servlet.xml

43 Injecting Actions Continued… - Finally, delegate Struts actions to Spring proxies

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

45 A Spring Service Locator 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

46 Example 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; }

47 Example continued… 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(); }

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

49 Spring AOP 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

50 AOP Concepts 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.

51 Aspects A way to modularize something, a concern, that may “cut across” multiple objects. Famous example: Declarative transaction management (EJB does this as well). Implemented as an advisor or an interceptor.

52 Jointpoints A point during program execution, such as a method invocation or an exception. In Spring, a joinpoint is always a method invocation.

53 Advice The action taken at a particular joinpoint. There are different types of advice: –Around –Before –Throws Spring uses an interceptor (or chain) around the joinpoint.

54 Pointcut A set of joinpoints specifying when an advice should fire. An AOP framework must allow the developer to specify pointcuts, for example, using regular expressions.

55 Introduction Adding methods or fields to an advised class. Spring allows you to introduce new interfaces to any advised object. Example: use Spring to make certain objects setter methods “locked” by making them implement a Lockable interface.

56 Target Object A target is the object that contains a joinpoint. Also known as: –Advised –Proxied

57 AOP proxy Any object created by the AOP framework, including advice. In Spring proxies are either: –JDK dynamic proxies – need interface –CGLIB proxies – don’t need interface

58 Weaving Assembling aspects to create an advised object. Can be done at compile time or at runtime. Spring performs weaving at runtime, whereas an AOP compiler, like AspectJ, is needed for compile time weaving.

59 Advice types Around –Most powerful –Surrounds a method invocation (allowing for work to be done before and after call). –Responsible for whether to proceed to the joinpoint, or return their own value. Before –Executes before joinpoint. –Has no power to prevent the joinpoint.

60 A few more types… Throws –Executed if the method throws an exception. –Provides strongly typed throws advice. After –Executed after a joinpoint executes normally.

61 More info… See the Spring Documentation chapter on AOP for more complex examples of Aspect Oriented Programming using the Spring Framework. –http://static.springframework.org/spring/doc s/1.2.x/reference/aop.html

62 Last words on AOP The biggest benefit that we get from AOP is declarative transaction management –Similar to EJB transactions –More later One last example: Custom AOP Logging –Logs when you arrive in a method –Logs when you exit a method –Calculates the time spent in a method

63 Logging Interceptor import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.apache.log4j.Logger; public class LoggingInterceptor implements MethodInterceptor { private static final Logger LOG = Logger.getLogger(LoggingInterceptor.class); public Object invoke(MethodInvocation methodInvocation) throws Throwable { String methodName = methodInvocation.getMethod().getDeclaringClass() + "::" + methodInvocation.getMethod().getName(); // log here when you enter // save the time in a temp variable // proceed with the method call, BUT ensure that you will get back after // proceed(), even if proceed fails return methodInvocation.proceed(); // log now that you done // calculate the time it took and log it }

64 Exercise: A little AOP Magic See the logging interceptor bean in SpringBeans.xml for the LoggingInterceptor.java class. It logs all beans that are a DAO or a Service (actually all beans that start with trn). Finish the LoggingInterceptor.java class –Logs when you arrive in a method –Logs when you exit a method –Calculates the time spent in a method and log it

65 Spring and OJB If you are going to use OJB in a project, Spring should be a requirement. This is true even if you do not use any other feature in Spring other than the O/R mapping support. Biggest benefits: –Declarative transaction management –DAO Support & Connection management

66 Declarative Transaction Management One of the big reasons people use EJB The opposite being Programmatic Transaction Management, which can also be done in Spring Done with AOP Is very configurable, though we will only cover a one- size fits all configuration, which we recommend until tuning is needed

67 Spring Configuration

68 Spring Config Continued… trn*Service

69 DAO Support Extend the Spring Helper Class org.springframework.orm.ojb.support.PersistenceBrokerDaoSupport –Need to inject a jcdAlias (see project for example) Provides a PersistenceBrokerTemplate Ensures PersistenceBrokers are opened and closed correctly Code automatically participates in transactions Thread-safe so can be instance variables

70 Recall: The OJB w/o Spring Way public void saveUser(User user) { PersistenceBroker broker = PersistenceBrokerFactory.defaultPersistenceBroker(); try { broker.beginTransaction(); broker.store(user); broker.commitTransaction(); } catch (Exception e) { broker.abortTransaction(); LOG.error("error retrieving stats", e); } finally { if (!broker.isClosed()) broker.close(); }

71 OJB with Spring public class UserDAOOjbImpl extends PersistenceBrokerDaoSupport implements UserDAO { public void saveUser(User user) { getPersistenceBrokerTemplate().store(user); } // lots of methods removed }

72 Longer Example public class UserDAOOjbImpl extends PersistenceBrokerDaoSupport implements UserDAO { public User findUser(String personId) { LOG.debug("Find user: "+personId); Criteria criteria = new Criteria(); criteria.addEqualTo("personId", personId); return (User) getPersistenceBrokerTemplate(). getObjectByQuery(new QueryByCriteria(User.class, criteria)); } public void saveUser(User user) { getPersistenceBrokerTemplate().store(user); } public boolean isUserBanned(String personId) { Criteria crit = new Criteria(); crit.addEqualTo("banPersonId", personId); long count = getPersistenceBrokerTemplate().getCount(new QueryByCriteria(BanUser.class, crit)); if (count > 0) { return true; } return false; } public List findAllBanUsers() { return (List) getPersistenceBrokerTemplate().getCollectionByQuery(new QueryByCriteria(BanUser.class)); } public void deleteBanUser(BanUser banUser) { getPersistenceBrokerTemplate().delete(banUser); } }

73 Exercise: Updating your DAO Modify your MovieDAOImpl to use the new Spring/OJB method

74 Using Spring to help Test By using Spring, your classes should be much easier to test because Spring is unobtrusive. –Should not depend on the container as it would if using something like EJB. –Since objects are injected via setters, everything can be set in a unit test… somewhat magically.

75 org.springframework.test Context caching –Speeds up test run time – don’t have to load the context files for each test. Dependency injection for test classes –Will auto-inject for each setter in a test. Appropriate test transaction management –Runs tests in a transaction that is rolled back after the test runs, resulting in “untouched” database. Using inherited instance variables –applicationContext: explicit bean lookup –jdbcTemplate: runs in same transaction (useful to query) Use the SIT Helper –Provides access to an OJB Persistence Broker (better for querying because the transaction doesn’t need to be flushed and you can use standard OJB criteria queries). –Common place to set up your test spring configuration.

76 Example public class ProjectServiceImplTest extends PersistenceBrokerAbstractTransactionalDataSourceSpringContextTests { private ProjectService projectService; private UserService userService; public UserService getUserService() { return userService; } public void setUserService(UserService userService) { this.userService = userService; } public ProjectService getProjectService() { return projectService; } public void setProjectService(ProjectService projectService) { this.projectService = projectService; }

77 Example continued… public void testSaveProject() { String projectName = "The jUnit Test Project"; String personId = "12345678900"; String username = "The jUnit Test Username"; String role = "The jUnit Test Role"; User user = new User(); user.setPersonId(personId); user.setUsername(username); getUserService().saveUser(user); Description description = new Description(); description.setDescription("This is a test."); Project project = new Project(); project.setActive(true); project.setCreateDate(new Timestamp((new Date()).getTime())); project.setDescription(description); project.setDueDate(new Timestamp((new Date()).getTime())); project.setProjectName(projectName); description.setProject(project); getProjectService().saveProject(project);

78 Example concluded RoleProjectUser roleProjectUser = new RoleProjectUser(); roleProjectUser.setRole(role); roleProjectUser.setProject(project); roleProjectUser.setUser(user); getProjectService().saveRole(roleProjectUser); Criteria criteria = new Criteria(); criteria.addLike("projectName", projectName); int count = getPersistenceBroker().getCount(new QueryByCriteria(Project.class, criteria)); assertEquals("Project [" + projectName + "] did not save properly.", count, 1); criteria = new Criteria(); criteria.addLike("role", role); count = getPersistenceBroker().getCount(new QueryByCriteria(RoleProjectUser.class, criteria)); assertEquals("Role [" + role + "] did not save properly.", count, 1); }

79 References Spring Framework Documentation –http://static.springframework.org/spring/doc s/1.2.x/reference/index.htmlhttp://static.springframework.org/spring/doc s/1.2.x/reference/index.html Martin Fowler’s Dependency Injection –http://martinfowler.com/articles/injection.html


Download ppt "Training - Day 4 The Spring Framework & Testing Web Applications."

Similar presentations


Ads by Google