Presentation is loading. Please wait.

Presentation is loading. Please wait.

Spring Cleaning How to do more with less XML Craig Walls Gateway Software Symposium (St. Louis) September 29, 2007

Similar presentations


Presentation on theme: "Spring Cleaning How to do more with less XML Craig Walls Gateway Software Symposium (St. Louis) September 29, 2007"— Presentation transcript:

1 Spring Cleaning How to do more with less XML Craig Walls Gateway Software Symposium (St. Louis) September 29, 2007 craig-sia@habuma.com

2 About you… Java?.NET? Ruby/Rails? Erlang? –Java 6? Java 5? Java 1.4? Java 1.3? 1.2 or older? Who’s using Spring? How long? –Spring 1.2? Spring 2? Spring 2.1?

3 About me Agile developer with Semantra –Natural language data access Developing software professionally for over 13 years –Telecom, Finance, Retail, Education –Java for most of that –Also some C/C++, C#/.NET, Ruby Spring fanatic

4 Spring sucks!

5 Spring sucks Spring is configured with XML XML is evil Evil sucks Therefore, Spring sucks

6 The so-called solutions to XML I don’t need no stinkin’ dependency injection! I’ll do it myself! Annotations

7 The truth about Spring and DI Spring != XML –Spring’s container is decoupled from its configuration strategy Spring is more than just DI –Spring is a full application framework

8 But I’ll concede that… DI is at the core of everything you do in Spring Spring DI typically involves lots of XML XML can be verbose Let’s see how to do more Spring with less XML

9 Three plans of attack Smarter XML - Use Spring XML trickery to reduce verbosity Annotations - Use annotations to configure Spring Scripting - Use scripting to configure Spring

10 Disclaimer There is no one-size-fits-all fix –Apply an ounce of pragmatism

11 Spring XML done smartly Honey, I shrunk the XML!

12 Smart Spring XML Shorthand XML Bean inheritence Property editors The “p” namespace Custom configuration Autowiring Arid POJOs (aka, extreme autowiring)

13 Shorthand XML Introduced in Spring 1.2 Original and elements replaced with value and ref attributes.

14 Shorthand XML in action Pre-Spring 1.2: This is a string value Spring 1.2+:

15 Shorthand XML: Tradeoffs Pros –More terse Cons –Can’t be used to when specifying values in collections (well…maybe)

16 Bean inheritence Available in Spring since ??? Declare common configuration details in a parent bean Create sub-beans that inherit from the parent

17 Bean inheritence example 1 <bean id="knightParent” class="com.springinaction.knight. KnightOfTheRoundTable" abstract="true"> Parent type and properties are inherited

18 Bean inheritence example 2 <bean id="knight" class="com.springinaction.knight. KnightOfTheRoundTable" parent="knightParent"> Only properties are inherited

19 Bean inheritence tradeoffs Pros –Helps keep Spring configurations more DRY Cons –A little tricky to navigate bean hierarchies…especially without tool support

20 Property editors Supported in all versions of Spring –Actually part of the JavaBeans spec Express complex configurations as simpler strings –Property editors help Spring convert simple strings to complex objects

21 Spring’s built-in property editors ByteArrayPropertyEditor CharacterEditor CharArrayPropertyEditor ClassArrayEditor ClassEditor CustomBooleanEditor CustomCollectionEditor CustomDateEditor CustomMapEditor CustomNumberEditor FileEditor InputStreamEditor LocaleEditor PatternEditor PropertiesEditor ResourceBundleEditor StringArrayPropertyEditor StringTrimmerEditor URIEditor URLEditor

22 Property editors in action In Java… public class KnightOnCall implements Knight {... private URL url; public void setUrl(URL url) { this.url = url; } private PhoneNumber phoneNumber; public void setPhoneNumber(PhoneNumber phoneNumber) { this.phoneNumber = phoneNumber; } In the XML… <bean id="knight" class="com.springinaction.knight.KnightOnCall">

23 Registering a customer editor <bean id="customEditorConfigurer" class= "org.springframework.beans.factory.config.CustomEditorConfigurer"> <bean id="phoneEditor" class= "com.springinaction.springcleaning.PhoneNumberEditor" />

24 Spring MVC & property editors In Spring MVC, you might configure SimpleUrlHandlerMapping like this… <bean id="urlMapping" class="org.springframework.web.servlet.handler. SimpleUrlHandlerMapping"> homeController loginController addSpittleController addSpitterController “mappings” is java.util.Properties

25 Spring MVC w/property editors But PropertiesEditor can make it simpler <bean id="urlMapping" class="org.springframework.web.servlet.handler. SimpleUrlHandlerMapping"> /home.htm=homeController /login.htm=loginController /addSpittle.htm=addSpittleController /addSpitter.htm=addSpitterController

26 Allow me to digress… Although not related to property mappings at all, Spring 2.0 introduces some handy XML- saving features… <bean id="urlMapping” class="org.springframework.web.servlet.mvc.support. ControllerClassNameHandlerMapping" /> ControllerClassNameHandlerMapping automatically maps controllers to URL patterns based on the controller’s class name.

27 Property editors tradeoffs Pros –Complex types that normally would require lines of XML can be expressed as simple strings Cons –Not always apparent what type is being created –Looks weird if you don’t know what’s going on

28 The “p” namespace New in Spring 2.0 Enables very terse injection of properties as attributes of the element Made available with… <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

29 “p” example <bean id="knight" class="com.springinaction.knight.KnightOfTheRoundTable" p:quest-ref="quest" p:horse-ref="horse" p:sword-ref="sword" p:armor-ref="armor" p:shield-ref="shield">

30 “p” namespace tradeoffs Pros –Super terse Cons –May seem alien to developers not familiar with it

31 Custom configuration elements Available since Spring 2.0 Encapsulate complex bean configuration behind simpler XML elements. Spring 2.0 comes with several out-of-the-box namespaces –aop, jee, lang, tx, util More coming in Spring 2.1: –context, jms Other Spring projects include (or will include) custom elements: –Spring Security, Spring Modules, etc

32 “jee” namespace example Configure JNDI object using : <property name="jndiName" value="/jdbc/RantzDatasource" /> Using : <jee:jndi-lookup id="dataSource" jndi-name="/jdbc/RantzDatasource" resource-ref="true" />

33 How to build custom element Create namespace schema (XSD) Create namespace handler class Create element parser class Create META-INF/spring.schemas –Maps schemas to physical XSD file Create META-INF/spring.handlers –Maps schemas to namespace handlers

34 Custom element tradeoffs Pros –Simplifies XML configuration –Enables domain-specific configuration –More expressive Cons –Hides what is really being configured (that may be a good thing, though)

35 Autowiring Spring’s so smart…let it figure out how to wire up your bean properties Autowiring comes in five flavors: –No - Do not autowire –byName - Inject beans into properties where the bean’s ID matches the property’s name –byType - Inject beans into properties where the bean’s type is assignable to a property –constructor - Choose a constructor where Spring can inject beans (by type) into the constructor’s arguments –autoDetect - Try constructor first, then byType

36 Autowiring Autowiring strategy can be specified on a per-bean basis or a per-XML file basis: –Per bean: Set the autowire attribute on the individual elements. Available in all versions of Spring –Per XML-file: Set the default-autowire attribute on the element. Available since Spring 2.0

37 Autowiring example (per bean) <bean id="knight” class="com.springinaction.knight.KnightOfTheRoundTable" autowire="byType"> Injects all properties Still must inject constructor args

38 Autowiring example (per file) <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="…" default-autowire="byType"> <bean id="knight" class="com.springinaction.knight.KnightOfTheRoundTable” autowire="no">... All beans will be autowired “byType” Unless overridden on each bean

39 Autowiring tradeoffs Pros –Can dramatically reduce the amount of XML in a Spring configuration Cons –Along with terseness comes lack of clarity. What was wired where? –Visualization tools (Spring IDE, BeanDoc) won’t recognize autowired beans as being wired. –byName autowiring couples configuration to implementation details –byType and constructor can be problematic when there are ambiguities

40 Arid POJOs Spring add-on by Chris Richardson (POJOs in Action) Available at http://code.google.com/p/aridpojos Turns auto-wiring up a notch –Automatically declare and autowire all beans in a specified package (or packages) Based on notion that all beans are declared similarly –Also has an auto-DAO feature

41 Arid POJOs Add to Spring config with… <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:arid="http://chrisrichardson.net/schema/arid" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://chrisrichardson.net/schema/arid http://chrisrichardson.net/schema/arid.xsd">

42 Arid POJOs example 1 Automatically declare all beans in a package and then autowire them “byType”… <arid:define-beans package="com.habuma.dao" autowire="byType" />

43 Arid POJOs tradeoffs All the same pros and cons as autowiring… –Just more so

44 Annotating Spring Dependency injection is where it’s @

45 Annotations and Spring Use @AspectJ for aspects Use @Transactional for transactions Spring JavaConfig Spring 2.1 annotations

46 Spring without @AspectJ Prior to Spring 2.0, AOP was a clumsy mess of XML:... This is just weird

47 Spring without @AspectJ Spring 2.0’s “aop” namespace made things a little bit better… <aop:after-returning method="sing" pointcut= "execution(* *.Knight.embarkOnQuest(..))" />

48 Spring with @AspectJ Spring 2.0 also introduced integration with @AspectJ –Now aspects require only minimal XML One bean declaration for each aspect class Not true AspectJ aspect –Still Spring proxy –Just uses @AspectJ annotations

49 @AspectJ example @Aspect public class Minstrel { @Pointcut("execution(* *.Knight.embarkOnQuest(..))") public void embark() {} @AfterReturning("embark()") public void sing() { System.out.println("Fa la la!"); System.out.println("The brave knight is embarking on a quest!"); }

50 @AspectJ example In the XML… Yep…that’s it.

51 @AspectJ tradeoffs Pros –Significantly less XML required for aspects Cons –Couples aspect classes to AspectJ –Not all AspectJ pointcuts available; still proxy-based

52 @Transactional Prior to Spring 2.0, transactions were just as messy as other types of aspects –TransactionProxyFactoryBean instead of ProxyFactoryBean –Bean inheritence helped a little

53 The “tx” namespace Spring 2.0 added the “tx” namespace Made things a bit simpler… <tx:method name="*" propagation="supports" read-only="true"/>

54 @Transactional Spring 2.0 also introduced the @Transactional annotation –Very appropriate use of annotations Transactions declared with minimal XML

55 @Transactional example In Java: @Transactional(propagation=Propagation.SUPPORTS) public class CustomerServiceImpl implements CustomerService { @Transactional(propagation=Propagation.REQUIRED) public void addNewCustomer(Customer customer) {... }... } In XML:

56 @Transactional tradeoffs Pros –Like @AspectJ, very very little XML required Cons –Invasive--Spring annotations couple your code to Spring

57 Spring JavaConfig Add-on for Spring –http://www.springframework.org/javaconfig Currently at version 1.0-M2a Recreates Spring XML configuration in Java using annotations Provides several annotations for Spring configuration: –@Configuration - Declares class as a configuration class –@Bean - Declares a method as a bean declaration –@ExternalBean - Declares an abstract method as a reference to an externally defined bean –@AutoBean - Declares an abstract method to server as a holder for automatically instantiated/wired bean –@ScopedProxy - Used to declare scoped proxy for a bean (non-singleton/non-prototype)

58 Spring JavaConfig Two ways to use JavaConfig: –Use AnnotationApplicationContext Simple, no-XML approach Hard to use with webapps Can’t parameterize configuration instances –Configure a ConfigurationPostProcessor (in XML) Easy to use with web apps (using minimal bootstrap XML) Configuration can be parameterized

59 Loading JavaConfig AnnotationApplicationContext: ApplicationContext ctx = new AnnotationApplicationContext( MyConfig.class.getName()); ConfigurationPostProcessor:

60 JavaConfig example @Configuration public abstract class KnightConfig { @Bean public Knight knight() { KnightofTheRoundTable knight = new KnightOfTheRoundTable("Bedivere"); knight.setQuest(quest()); return knight; } @Bean private Quest quest() { return new HolyGrailQuest(); } @ExternalBean private abstract Horse horse(); }

61 JavaConfig tradeoffs Pros –Minimally invasive - annotations are confined to configuration-specific classes –Dynamic - Use any Java constructs you like –Testable - Easily write unit tests against configuration itself –Refactorable - No static identifiers –Offers bean visibility using Java constructs –Parameterizable if using bootstrap XML Cons –Non-intuitive - Structured like Spring XML, but looks like Java

62 Spring 2.5 annotations Spring 2.5 will add a few new annotations –@Component - Indicates that a class is a component that should be registered in Spring –@Autowired - Indicates that a property should be autowired –@Scoped - Declares scoping on auto-detected bean Works with new configuration element

63 Scans a package and all of its subpackages Auto-configures all beans annotated with @Component, @Repository, or @Aspect Autowires (byType) all properties and methods that are annotated with @Autowired Also supports some JSR-250 annotations –@PostConstruct, @PreDestroy, @Resource, @Resources

64 Spring 2.5 annotation example @Component("knight") public class KnightOfTheRoundTable implements Knight { private String name; private Quest quest; private Horse horse;... public KnightOfTheRoundTable(String name) { this.name = name; } @Resource public void setQuest(Quest quest) { this.quest = quest; } @Autowired private void myKingdomForAHorse(Horse horse) { this.horse = horse; }

65 Spring 2.5 annotation example <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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.1.xsd"> <context:component-scan base-package="com.springinaction.knight" /> <bean id="knight" class="com.springinaction.knight.KnightOfTheRoundTable">

66 Spring 2.5 annotation tradeoffs Pros –Moves configuration details closer to the beans being configured (DRY) –Injection no longer limited to public setter methods and constructors Cons –Moves configuration details closer to the beans being configured (invasive) –Could be static identifiers

67 Scripting Spring Cut XML and be buzzword compliant at the same time

68 Scripting Spring Configuration Springy (JRuby) Grails Spring Builder (Groovy)

69 Springy Provides a Ruby DSL for configuring a Spring application context –http://code.trampolinesystems.com/springy –Current version is 0.2 –Apache license

70 Loading a Springy context Programatically: ApplicationContext ctx = new JRubyApplicationContext( new ClassPathResource("com/habuma/samples/ctx.rb") ); No obvious way to use with web applications…bummer…

71 Springy example bean :knight, "com.springinaction.knight.KnightOfTheRoundTable" do |b| b.new "Bedivere” b.quest = :quest... end bean :quest, "com.springinaction.knight.HolyGrailQuest" do |b| b.new end

72 Springy example 2 Can you do this in Spring XML? for num in (1..10) bean :"knight#{num}", "com.springinaction.knight.KnightOfTheRoundTable" do |b| b.new "Bedivere" b.quest = :quest end

73 Springy and inline XML If you absolutely must use XML… inline_xml do <<XML <bean id="dragonQuest" class="com.sia.knight.SlayDragonQuest" /> XML end

74 Springy: Serialize to XML Get Spring XML from a JRuby-defined context: ((JRubyApplicationContext) ctx).getContextAsXml();

75 Springy tradeoffs Pros –Completely XML free Unless you want to inline some XML –All of JRuby available for defining a Spring context Cons –Serializes to XML then reloads it Performance implications –No clear way to use in a web app

76 Grails Spring Bean Builder Provides a Groovy DSL to configure a Spring context Part of Grails –In grails-core-0.5.6.jar –http://www.grails.org/Spring+Bean+Builder

77 Bean Builder example def bb = new grails.spring.BeanBuilder() bb.beans { quest(HolyGrailQuest) {} horse(Horse) {} sword(Sword) {} shield(Shield) {} armor(Armor) {} knight(KnightOfTheRoundTable, "Bedivere") { delegate.quest = quest delegate.horse = horse delegate.sword = sword delegate.shield = shield delegate.armor = armor } ApplicationContext ctx = bb.createApplicationContext() def knight = ctx.getBean("knight") knight.embarkOnQuest()

78 Bean Builder tradeoffs Pros –Completely XML free –Can use all of Groovy’s goodness to configure Spring Cons –Not clear how to use it outside of a Groovy script –Not clear how to use it in a web app (aside from Grails) –(just a nit) Not separate from Grails Must include Grails in your application classpath

79 Recap He made the XML shorter…too bad he couldn’t have done the same thing with the presentation

80 What we have learned Spring XML sucks… –If you don’t take advantage of the tricks to cut the clutter Spring and annotations : Not a zero sum game –Spring encourages proper use of annotations (and tolerates improper use) Spring != XML –Spring is more than just a configuration mechanism –JRuby, Groovy, and annotation configuration alternatives

81 A few final Spring tips You don’t have to wire everything! –Use sensible defaults –Case in point: Spring MVC command controllers commandName and commandClass properties Remember that there are two types of configuration… –Internal: Use Spring –External: Perhaps PropertyPlaceholderConfigurer or PropertyOverrideConfigurer Don’t put all of your beans in one XML file –Break your Spring context down –Perhaps by application layer or functional divisions

82 Q & A Don’t forget to turn in evals!!! http://www.springinaction.com craig-sia@habuma.com


Download ppt "Spring Cleaning How to do more with less XML Craig Walls Gateway Software Symposium (St. Louis) September 29, 2007"

Similar presentations


Ads by Google