Your SlideShare is downloading. ×
0
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Spring 3: What's New
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Spring 3: What's New

1,994

Published on

Published in: Technology, News & Politics
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,994
On Slideshare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
61
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \nThe createRedirect shown is a hack to avoid nasty exposed model attributes. Credit for this code goes to David Ehringer:\n\n private ModelAndView createRedirect(Yacht yacht) {\n String yachtKey = yacht.getKey();\n RedirectView redirect = new RedirectView("/yacht/" + yachtKey, true);\n // We are doing this rather than simply returning the String version of\n // the view (i.e. redirect:/groups/groupKey) because in the current\n // version of Spring all the model attributes get appended to the URL\n // which is nasty.\n redirect.setExposeModelAttributes(false);\n return new ModelAndView(redirect);\n }\n
  • \n
  • \n
  • Possibilities for ESAPI!\n
  • You can also use <mvc:annotation-driven />, but this often registers two conflicting instances of javax.validation.Validator, and causing an ambiguous bean reference exception on the @Autowired injection line in this example. It is easier to explicitly define an instance as above.\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Transcript

    • 1. Spring 3An overview of changes from version 2.5 Ted Pennings 8 December 2010
    • 2. Overview of Changes Annotations Fewer interfaces MVC overhaul Dropped binary compatibility with Java 1.4 Java 5 generics, for(), autoboxing, etc
    • 3. Spring 3 = Annotations Spring 3 emphasizes annotation config @Component, @Configuration, etc JSR 250 Common Annotations JSR 299/330 Bean Injection JSR 303 Bean Validation Java Persistence API (JPA)
    • 4. Enabling Annotation Configuration<context:component-scan base-package=”com.foo.bar”><mvc:annotation-driven>also, <aspectj:auto-proxy /> for @Aspects
    • 5. Annotation Config Example<?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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- Scans within the base package of the application for @Components to configure as beans --> <context:component-scan base-package="com.tedpennings.bu.cs667" /> <mvc:annotation-driven /></beans>
    • 6. Annotation Taxonomy@Component and its specializations @Service, @Repository @Controller@Configuration + @Bean@Autowired@Value
    • 7. @Component Example @Component("rssView")public class RomeRssView extends AbstractView { @Override protected void renderMergedOutputModel(Map model,HttpServletRequest request, HttpServletResponseresponse) throws Exception { doStuff(); }}
    • 8. @Service Example @Servicepublic class TwitterStatusProvider implements StatusProvider { @Autowired private CacheRepository cache; @Override public String getStatus(boolean skipCache) { String status = cache.findString(CACHE_KEY); if (skipCache || status == null) { status = getStatusFromTwitter(); cache.cacheString(CACHE_KEY, status, DEFAULT_CACHE_EXPIRY); } return status; }}
    • 9. @Configuration ClassesJava classes that do the work of XMLApplication Context filesAllow much more control over object creationInstantiated before XML beans @Configuration @Beans can be referenced by XML beans/config Can also reference XML beans
    • 10. @Config Example @Configurationpublic class MongoConfiguration { @Value("${db.host}") private String dbHost; @Value("${db.port}") private int dbPort; @Bean @Lazy public Mongo mongo() throws UnknownHostException { return new Mongo(dbHost, dbPort); }}
    • 11. MVC ChangesController interfaced dropped@RequestMapping instead of XML config@Controller instead of explicit XML configLots of return types possibleSimplicity
    • 12. The Simplicity of Controllers@Controller makes a class a controller “bean” Specialization of @Component@RequestMapping defines the URL paths handled by aclass and/or method. It is possible to nest paths, as in example on next slide. Many different RequestMethods allowed in a @Controller {} in @RM path define @PathVariable/@ReqParamValue of Inheritance Annotation caveat
    • 13. @Controller Example @Controller@RequestMapping({ "/yacht", "/yachts", "/mah-boats" })public class YachtController { @Autowired private YachtService service; private static final String YACHT_PAGE_VIEW = "yachts/view"; @RequestMapping(value = "/{yachtKey}", method = GET) public String displayYacht(@PathVariable(“yachtKey”) String yachtKey,Model model) { LOG.debug("Displaying Yacht " + yachtKey); Yacht yacht = service.findYachtByKey(yachtKey); model.addAttribute("yacht", yacht); return YACHT_PAGE_VIEW; }}
    • 14. MVC Annotations@Controller – an MVC Controller@RequestMapping@ModelAttribute@RequestParam and @PathVariable@SessionAttributes
    • 15. DemoAnnotation ConfigWorking formsBean validation (JSR-303)
    • 16. Controller Method Return Types@Controller methods can return many different types. Often: Model ModelAndView (use Model.setView(View) or Model.setViewName(String)) Distinction between View and View Name String for the view name to displayCan return void if you’ve drank plenty of convention over configurationkoolaid. Dangerous if you refactor a lot (or the next person does).Methods can also be annotated with @RequestBody Used to return a value without going through MVC apparatus Generally bad form, but good for testing or mock apps. @ModelAttribute has the same two distinct meanings as @ModelAttribute
    • 17. Bean Validation (JSR-303)Constraints are defined by @Entity public class Yacht {annotations on the actual data @Id @GeneratedValue(strategy = GenerationType.AUTO)entities private Long id;Validation is executed @Size(min = 4, max = 35, message = "Key must be between {min} and {max} characters long.")automagically by framework @NotEmpty(message = "Key is required.") @Pattern(regexp = "[A-Za-z0-9_-]*", message = "Only letters, numbers, underscores and hyphens may be used.")User-friendly errors appear private String key;automagically on the view. @Size(min = 4, max = 35, message = "Name must be between {min} and {max} characters long.")Object graphs can be traversed @NotEmpty(message = "Name is required.") private String name;and nested objects are validated @ValidDate(or not, if you wish). private Date acquisitionDate; }
    • 18. Setting Up And Using Bean ValidationAs simple as @Valid Can be applied inside domain to validate child/2nd degree objectsBindingResult for errors MUST be argument after @Valid argument (quirk) RuntimeException if not toString() is your friend.Validating a large object graph is risky. Complicates future changes On the other hand, very hard to merge BindingResults
    • 19. Updated Controller@Controllerpublic class YachtController {@RequestMapping(method = POST)public ModelAndView saveYacht(@Valid Yacht yacht, BindingResultresult, ModelAndView mv) { LOG.debug("Attempting to save Yacht: " + yacht.getKey()); if (result.hasErrors()) { LOG.debug("Submission has errors " + result); mv.setViewName(MODIFY_YACHT_VIEW); return mv; } service.store(yacht); FlashMap.setSuccessMessage("Successfully saved Yacht"); return createRedirect(yacht);}}
    • 20. Handling Validation ErrorsEnsure that you have a BindingResult.hasErrors() check in @Controller When returning edit view, ensure all needed model attributes are present This includes the object being validated if you construct a new Model/ MVYou may need a call to the root-level form:errors in order to capture object-level errors (not field-level). <form:errors path=“” />Be sure you interrupt flow so you don’t persist invalid objects VALIDATION ERRORS ARE NOT EXCEPTIONSThere is a Hibernate option to validate pre-persist, but this is nuanced Legacy objects May be incompatible with Spring-managed dependencies
    • 21. Writing Your Own ConstraintsConstraints can be combined and composed For example, @NotEmpty actually means @NotNull, @Size(min=1) & @ReportAsSingleViolationWrite an annotation class @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented (or not) @Constraint(validatedBy = YourCustomValidator.class) Be sure to add a default message These can be Java properties read from a file (Internationalization/i18n)Write a validator Implement ConstraintValidator<AnnotationType, TargetClass> Return boolean for isValid(TargetClass object, …) Statefulness (via initialize() method) Dependency Injection, Constructors, and Hibernate ORM issue
    • 22. Writing Unit Tests For Validation Magic A lot of JSR-303 is wizardry and magic beans. Write unit tests so you ensure code execution is predictable. Easiest to write using Spring’s JUnit Test Runner Point to an application context field that contains <bean id="validator“ class="org.springframework.validation.beanvalidation.Loca lValidatorFactoryBean" /> Ensure a JSR-303-compliant validator is on your test classpath Eg, Hibernate Validator
    • 23. Example Unit Test @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({ "classpath:your-persistence.xml", "classpath:your-persistence-test.xml" }) public class YachtValidationTest { @Autowired private javax.validation.Validator validator; private Yacht emptyYacht; @Before public void setUpEmptyYacht() { emptyYacht = new Yacht(); } @Test public void theKeyFieldIsRequired() { Set<ConstraintViolation<Yacht>> constraintViolations = validator .validate(emptyYacht); boolean containsYachtKeyViolation = false; for (ConstraintViolation<Yacht> violation : constraintViolations) { if ("key".equals(violation.getPropertyPath().toString()) && violation.getMessageTemplate().contains("required")) { containsYachtKeyViolation = true; } } assertTrue(containsYachtKeyViolation); } }
    • 24. Even More AnnotationsJSR 250 Resource ManagementJSR 299/330 Bean InjectionJPA!
    • 25. JSR 250 Resource Management@Resource (typically fields)@PostConstruct (method) Replaces InitializingBean + afterPropertiesSet()@PreDestroy (method) Replaces DisposableBean + destroy()
    • 26. Bean Injection JSRjavax.inject package: @Inject (equivalent to @Autowired) @Qualifier (to resolve ambiguities) @Named @Scope @Singleton
    • 27. JPA Annotations@PersistenceContext / @PersistenceUnit@Entity@Column, @Id, @Enumerated, @ManyToOne, etcMixes well with Spring-tx and @Transactional
    • 28. Basic JPA Configuration in Spring 3.0 PersistenceAnnotationBeanPostProcessor for @PersistenceContext/Unit EntityManagers LocalContainerEntityManagerFactoryBean to bootstrap JPA and read persistence.xml Still need to configure provider, eg, Hibernate Need to provide data source, either as a constructed bean or JNDI reference
    • 29. Hibernate as JPA Provider HibernateJpaVendorAdapter + Properties <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="showSql" value="true" /> <property name="generateDdl" value="true" /> <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" /> </bean> <bean id="hibernateProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <property name="locations"> <list> <value>classpath:hibernate.properties</value> hibernate.properties: </list> </property> hibernate.hbm2ddl.auto=update </bean> hibernate.connection.autocommit=true hibernate.show.sql=true <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" hibernate.generate_statistics=true destroy-method="close"> javax.persistence.validation.mode=ddl hibernate.dialect=org.hibernate.dialect.MySQL5Dialect <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/yourdb" /> <property name="username" value="user" /> <property name="password" value="pass" /> </bean>
    • 30. Resourceshttp://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/http://static.springsource.org/spring/docs/3.0.x/javadoc-api/Spring In Action, 3rd Edition by Craig Walls(Manning). Excellent survey.
    • 31. Questions?http://ted.pennin.gs /ted@pennin.gs@thesleepyvegan on twitter not always Java related

    ×