Download presentation
Presentation is loading. Please wait.
Published byGilbert Patterson Modified over 9 years ago
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
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.