spring 3: what's new

31
Spring 3 An overview of changes from version 2.5 Ted Pennings 8 December 2010

Upload: ted-pennings

Post on 13-Jan-2015

1.975 views

Category:

Technology


9 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Spring 3: What's New

Spring 3An overview of changes from version 2.5

Ted Pennings

8 December 2010

Page 2: Spring 3: What's New

Overview of Changes

Annotations

Fewer interfaces

MVC overhaul

Dropped binary compatibility with Java 1.4

Java 5 generics, for(), autoboxing, etc

Page 3: Spring 3: What's New

Spring 3 = AnnotationsSpring 3 emphasizes annotation config

@Component, @Configuration, etc

JSR 250 Common Annotations

JSR 299/330 Bean Injection

JSR 303 Bean Validation

Java Persistence API (JPA)

Page 4: Spring 3: What's New

Enabling Annotation Configuration

<context:component-scan base-package=”com.foo.bar”>

<mvc:annotation-driven>

also, <aspectj:auto-proxy /> for @Aspects

Page 5: Spring 3: What's New

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>

Page 6: Spring 3: What's New

Annotation Taxonomy

@Component and its specializations

@Service, @Repository

@Controller

@Configuration + @Bean

@Autowired

@Value

Page 7: Spring 3: What's New

@Component Example

@Component("rssView")public class RomeRssView extends AbstractView {

@Override protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { doStuff();

}

}

Page 8: Spring 3: What's New

@Service Example@Service

public 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; }

}

Page 9: Spring 3: What's New

@Configuration Classes

Java classes that do the work of XML Application Context files

Allow much more control over object creation

Instantiated before XML beans

@Configuration @Beans can be referenced by XML beans/config

Can also reference XML beans

Page 10: Spring 3: What's New

@Config Example@Configuration

public 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); }

}

Page 11: Spring 3: What's New

MVC ChangesController interfaced dropped

@RequestMapping instead of XML config

@Controller instead of explicit XML config

Lots of return types possible

Simplicity

Page 12: Spring 3: What's New

The Simplicity of Controllers

@Controller makes a class a controller “bean”Specialization of @Component

@RequestMapping defines the URL paths handled by a class 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/@ReqParam

Value of InheritanceAnnotation caveat

Page 13: Spring 3: What's New

@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; }

}

Page 14: Spring 3: What's New

MVC Annotations

@Controller – an MVC Controller

@RequestMapping

@ModelAttribute

@RequestParam and @PathVariable

@SessionAttributes

Page 15: Spring 3: What's New

DemoAnnotation Config

Working forms

Bean validation (JSR-303)

Page 16: Spring 3: What's New

Controller Method Return Types

@Controller methods can return many different types. Often:ModelModelAndView (use Model.setView(View) or Model.setViewName(String))

Distinction between View and View NameString for the view name to display

Can return void if you’ve drank plenty of convention over configuration koolaid.

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

Page 17: Spring 3: What's New

Bean Validation (JSR-303)

Constraints are defined by annotations on the actual data entities

Validation is executed automagically by framework

User-friendly errors appear automagically on the view.

Object graphs can be traversed and nested objects are validated (or not, if you wish).

@Entitypublic class Yacht {

@Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id;

@Size(min = 4, max = 35, message = "Key must be between {min} and {max} characters long.") @NotEmpty(message = "Key is required.") @Pattern(regexp = "[A-Za-z0-9_-]*", message = "Only letters, numbers, underscores and hyphens may be used.") private String key;

@Size(min = 4, max = 35, message = "Name must be between {min} and {max} characters long.") @NotEmpty(message = "Name is required.") private String name;

@ValidDate private Date acquisitionDate;

}

Page 18: Spring 3: What's New

Setting Up And Using Bean Validation

As simple as @ValidCan be applied inside domain to validate child/2nd degree objects

BindingResult for errorsMUST be argument after @Valid argument (quirk)RuntimeException if nottoString() is your friend.

Validating a large object graph is risky.Complicates future changesOn the other hand, very hard to merge BindingResults

Page 19: Spring 3: What's New

Updated Controller@Controllerpublic class YachtController {

@RequestMapping(method = POST)public ModelAndView saveYacht(@Valid Yacht yacht, BindingResult result, 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);}

}

Page 20: Spring 3: What's New

Handling Validation Errors

Ensure that you have a BindingResult.hasErrors() check in @ControllerWhen returning edit view, ensure all needed model attributes are presentThis includes the object being validated if you construct a new Model/MV

You 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 objectsVALIDATION ERRORS ARE NOT EXCEPTIONS

There is a Hibernate option to validate pre-persist, but this is nuancedLegacy objectsMay be incompatible with Spring-managed dependencies

Page 21: Spring 3: What's New

Writing Your Own Constraints

Constraints can be combined and composed For example, @NotEmpty actually means @NotNull, @Size(min=1) & @ReportAsSingleViolation

Write 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 validatorImplement ConstraintValidator<AnnotationType, TargetClass>Return boolean for isValid(TargetClass object, …)Statefulness (via initialize() method)Dependency Injection, Constructors, and Hibernate ORM issue

Page 22: Spring 3: What's New

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 RunnerPoint to an application context field that contains

<bean id="validator“ class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />

Ensure a JSR-303-compliant validator is on your test classpath

Eg, Hibernate Validator

Page 23: Spring 3: What's New

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); }}

Page 24: Spring 3: What's New

Even More Annotations

JSR 250 Resource Management

JSR 299/330 Bean Injection

JPA!

Page 25: Spring 3: What's New

JSR 250 Resource Management

@Resource (typically fields)

@PostConstruct (method)

Replaces InitializingBean + afterPropertiesSet()

@PreDestroy (method)

Replaces DisposableBean + destroy()

Page 26: Spring 3: What's New

Bean Injection JSRjavax.inject package:

@Inject (equivalent to @Autowired)

@Qualifier (to resolve ambiguities)

@Named

@Scope

@Singleton

Page 27: Spring 3: What's New

JPA Annotations

@PersistenceContext / @PersistenceUnit

@Entity

@Column, @Id, @Enumerated, @ManyToOne, etc

Mixes well with Spring-tx and @Transactional

Page 28: Spring 3: What's New

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

Page 29: Spring 3: What's New

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> </list> </property> </bean>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <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>

hibernate.properties:

hibernate.hbm2ddl.auto=updatehibernate.connection.autocommit=truehibernate.show.sql=truehibernate.generate_statistics=truejavax.persistence.validation.mode=ddlhibernate.dialect=org.hibernate.dialect.MySQL5Dialect

Page 31: Spring 3: What's New

Questions?

http://ted.pennin.gs /[email protected]

@thesleepyvegan on twitter

not always Java related