560 likes | 790 Views
Spring: What’s it all about?. Rod Johnson Interface21. Topics. Aims of Spring Enabling technologies Core Spring modules Common concepts Spring architectures Working with Spring The Spring community. Aims of Spring. Enable applications to be coded from POJOs
E N D
Spring:What’s it all about? Rod Johnson Interface21
Topics • Aims of Spring • Enabling technologies • Core Spring modules • Common concepts • Spring architectures • Working with Spring • The Spring community
Aims of Spring • Enable applications to be coded from POJOs • Allow enterprise services to be applied to those POJOs in a declarative, non-invasive way • Examples • POJOs can be made transactional without the need to know about transaction APIs • POJOs can be exposed for management via JMX without the need to implement an MBean interface • …
POJO development • POJO stands for Plain Old Java Object • A POJO is not bound to any environment • No imports of classes that bind it to a specific environment • Only uses framework classes that offer good abstraction like Spring’s persistence framework • Not dependent on a particular lookup mechanism • Collaborating instances are injected using plain Java constructors or setter methods • True POJOs are testable in isolation
Applying services to POJOs declaratively • Decouples your application objects from their environment • Brings leverage, enables reuse • Actually more powerful than traditional invasive component models • Lets you scale up or down without rewriting application code • Examples • Switch to global transactions over JTA • Export your business objects in different environments • Switch between SLSB, web service, write/take from JavaSpace etc. • …
Enabling technologies: The Spring Triangle Power to the POJO Consistent service abstractions AOP IOC
Core Spring modules • Core Lightweight Container • The heart of Spring • Aspect-Oriented Programming (AOP) framework • Modularizes behavior that would otherwise be scattered through different methods • Decorates your POJOs with cross-cutting behavior in a transparent manner
The Core Lightweight Container • Facilitates: • Full-stack POJO-based application development • Within any environment: • Servlet, Portlet, EJB, Integration Test, Standalone, Rich Client • By providing: • A powerful object factory that manages the instantiation, configuration, decoration, and assembly of your business objects
The Spring Container in Action As a sophisticated object factory: Your Business Objects (POJOs) The Spring Lightweight Container Configuration Metadata produces Magic Happens Here Fully configured system Ready for Use
Key architectural enablers • Lets you view your application as a set of components • Each component is a POJO focused on solving your domain problem • Each component is testable in isolation • Each component has minimal dependencies • And dependencies can be easily mocked • The container manages the “glue code” required for component configuration and assembly • The container leverages advanced techniques for decorating your components at runtime
Realized benefits • Portability • Your core business logic is implemented once and runs anywhere • Leverage • Your core code is decoupled from volatile infrastructure • Business logic represents key asset • Should have a long life • Consistency • Common configuration strategy everywhere • Productivity • Enables parallel, test-driven development • Don’t need to reinvent your own infrastructure
Core Spring Modules (continued) • Next set of core modules are Java/J2EE support libraries focused on developer ease-of-use • Build on lower-level APIs like JDBC and JTA to: • Capture best practice usage • Eliminate boilerplate code • Provide consistency • Provide choice • Spring is not monolithic • You use just what you need
Spring modules (2) • Data access abstraction • Enables consistent architectural approach to data access • Delivers on JDBC simplification • Integrates with all leading O/R mapping frameworks • Transaction management abstraction • Supports “global” transactions over JTA (managed by an application server) • Supports “local” transactions over a single data source (with JDBC, Hibernate, JDO, OJB or custom data access API)
Spring modules (3) • J2EE API simplification • For working with JNDI, JTA, and other J2EE APIs • Eliminates boilerplate code that “doesn’t do anything” • Lightweight remoting • POJO-based remoting over a range of protocols • Includes support for RMI, IIOP, Hessian, Burlap, Axis, and other web services protocols
Spring modules (4) • JMS support • Provides support for sending and receiving JMS messages in a much simpler way than provided through standard J2EE. • JMX support • Supports JMX-enabled management of your application objects • Comprehensive testing strategy for application developers • Dependency Injection facilitates unit testing • Unique solution for integration testing outside an application server
Spring modules (5) • MVC web framework • Request-based MVC web framework • Event-driven Web Flow framework • All other Spring features can also be used with other web frameworks such as Struts or JSF • Integration • Spring is an increasingly important integration technology • Quartz (Spring) • Jasper Reports (Spring) • OSWorkflow / XFire / Cayenne… (other project) • Provides a strong, general component model • Core concepts applicable in many areas…
Common concepts • IOC / Dependency Injection • AOP • The “template” pattern • Exception hierarchies
Dependency Injection • A specialization of Inversion of Control • A Dependency Injection container manages application objects, taking care of “wiring” (how objects locate collaborators) • Container instantiates objects andinjects dependencies on collaborating objects and configuration properties through Java methods • Hollywood Principle • “Don’t call me, I’ll call you”
Setter Injection public class ServiceImpl implements Service { private int timeout; private AccountDao accountDao; public void setTimeout(int timeout) { this.timeout = timeout; } public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } // Business methods from Service … <bean id="service" class="com.mycompany.service.ServiceImpl"> <property name="accountDao" ref="accountDao"/> <property name="timeout" value="30" /> </bean>
Constructor Injection public class ServiceImpl implements Service { private int timeout; private AccountDao accountDao; public ServiceImpl(int timeout, AccountDao accountDao){ this.timeout = timeout; this.accountDao = accountDao; } // Business methods from Service <bean id="service" class="com.mycompany.service.ServiceImpl"> <constructor-arg value="30" /> <constructor-arg ref="accountDao" /> </bean>
Dependency Injection: Summary • Dependencies are expressed in pure Java • Push configuration (container injects dependencies) is much better than pull configuration (objects look up dependencies) • No ad hoc lookup • Code is self-documenting, describing its own dependencies • Can apply consistent management strategy everywhere • Easy to test • No JNDI to stub, properties files to substitute, RDBMS data to set up…
Dependency Injection in Practice • Simple (configuration) or object properties • Configuration (timeout) • Dependencies on collaborators (accountDao) • Configuration properties are also important • Can run many existing classes unchanged • “Autowiring” • Trivial to test or reuse application classes outside the container • Value adds such as hot swapping, instance pooling (with AOP)
Dependency Injection in Practice public class MyClient { public void setWeatherService(WeatherService ws) { this.weatherService = ws; } ... <bean id="weatherService" class="spring...SimpleRemoteStatelessSessionProxyFactoryBean" > <property name="businessInterface" value="...WeatherService" /> <property name="jndiName" value="ejb/weatherService" /> </bean> <bean id="myClient" class="...MyClient" autowire="autodetect" /> • No service locator or “plumbing” code
Switch to Local POJO <bean id="weatherService" class="...DefaultWeatherService"> <property name="countryCode" value="353" /> <property name="dataSource" ref="dataSource" /> </bean> • Change to a single bean definition • No change to Java code
Switch to Web Service <bean id="weatherService" class=“spring...HessianProxyFactoryBean"> <property name="serviceUrl" value= " http://server:8080/weather" /> <property name="businessInterface" value="...WeatherService" /> </bean> • Again, change is localized • Callers simply work with the business interface • Zero “plumbing” code
Implications for testability public void testForMyClient() { MyClient mc = new MyClient(); mc.setWeatherService(myMockService); // Test mc } • Imagine how much harder testing would be if we hadn’t use DI to factor out the JNDI lookup and EJB API calls…
Advanced Dependency Injection • Management of lists, maps or sets, with arbitrary nesting • Creation of objects using new or from factory methods • Object instances can be shared or non-singleton (per user) • Method Injection • Container can override abstract or concrete methods at runtime • Can use to avoid dependence on Spring container • Override moves dependency on Spring API from code to configuration • Nearly any existing Java object can be used in a Spring context • Leverages standard JavaBeans PropertyEditor machinery • Register custom property editors • Many hooks to customize container behaviour
Why AOP? • Dependency Injection takes us a long way, but is not quite enough on its own • AOP complements IoC to deliver a non-invasive framework • Externalizes crosscutting concerns from application code • Concerns that cut across the structure of an object model • AOP offers a different way of thinking about program structure to an object hierarchy • EJB interception is conceptually similar, but not extensible and imposes too many constraints on components • Can’t define new aspects • Constrained pointcut model (methods on the component interface)
AOP Example: Advice (interceptor) public class DebugInterceptor implements MethodInterceptor { public Object invoke(MethodInvocation mi) throws Throwable { try { Object retval = mi.proceed(); System.out.println("Succeeded!"); return retval; } catch (Throwable t) { System.out.println("Failed: " + t); } } }
How does an interceptor chain work? Control flows back through interceptor chain to return result to caller Caller invokes proxy, not target Proxy invokes interceptors Forward processing of interceptor chain concludes with invocation of method on target object
AOP • Using a pointcut we can apply this advice to many methods • Code that would otherwise appear in many places appears just once • Modularization avoids duplication and helps maintainability • Integration of DI and AOP allows aspects to be configured by Dependency Injection
What is an Advisor? • Combines what to do (advice) with where to do it (pointcut) to encapsulate a cross-cutting concern public void processSalary() { } public void checkInventory() { } public Object invoke(MethodInterceptor mi) throws Throwable { } Pointcut Advice
Usages of AOP • Out-of-the box aspects • Declarative transaction management for POJOs • Acegi Security for Spring • Custom aspects • Auditing • Exception handling • Performance monitoring • …
Common concepts • IOC / Dependency Injection • AOP • The “template” pattern • Exception hierarchies
The Template Pattern • Another form of Inversion of Control • Moves control into the framework through a callback • Solves problems common to many APIs • Resource acquisition/release • Exception translation • Provides convenience methods for many APIs • Avoid the evil TCFTC • try/catch/finally { try/catch }
Templates in a nutshell int userCount = jdbcTemplate.queryForInt( "SELECT COUNT(0) FROM USER"); • Where is connection acquired and released? • What happens in event of exceptions? • Enables developer to focus on expressing intent (in this case, SQL)
Templates (2) public Collection findRequestsEligibleForReminder() throws DataAccessException { return getJdbcTemplate().query( "SELECT NAME, DATE, ... “ + “ FROM REQUEST WHERE ORIGINATOR = ‘Rod’", new RowMapper() { public Object mapRow( ResultSet rs, int rowNum) throws SQLException { Request r = new Request(); r.setName(rs.getString("NAME")); r.setDate(rs.getDate("DATE")); return r; } }); } Callback Compiler picks up errors
Templates add value to… • JDBC • TopLink / Hibernate / JDO / other ORM • JMS • JavaMail • JNDI • … • Powerful concept leveraged consistently for many APIs
Templates work with Spring exception hierarchies… (1) • Framework exceptions like SQLException are translated to a common exception hierarchy. • Provides context information for debugging • Keeps stack trace intact • Translation mechanism is configurable and extensible • Converts checked exceptions into unchecked exceptions • Catching checked framework exceptions doesn’t add value, errors are usually unrecoverable • Same exception hierarchy regardless of framework you choose • Data access exception hierarchy is the same for all persistence tools (JDBC, Hibernate, JDO, …)
DataAccessException UncategorizedDataAccessException DataAccessResourceFailureException CleanupFailureDataAccessException DataIntegrityViolationException InvalidDataAccessApiUsageException DeadlockLoserDataAccessException InvalidDataAccessResourceUsageException OptimisticLockingFailureException ObjectRetrievalFailureException ObjectOptimisticLockingFailureException IncorrectUpdateSemanticsDataAccessException TypeMismatchDataAccessException Templates work with Spring exception hierarchies… (2) DataRetrievalFailureException
Spring-based architectures (1) • Adopt a layered architecture • Layering is typically logical • May not be physical • Fowler’s First Law of Distributed Objects • Don’t distribute your objects • If you need distribution, see Spring Remoting
Spring-based architectures (2) Remote exporters Presentation tier JSP, JSF, Velocity, Jasper Reports… Middle tier definitions Service objects / Business Facades (analogous to SLSBs) Transactional boundaries Domain objects Spring web-tier context DAO interfaces DAO implementations RDBMS JDBC/ ORM
Spring-based architectures (3) • Lightweight Container Architecture • J2EE Design and Development (Johnson, 2002) • J2EE without EJB (Johnson/Hoeller, 2004) • Spring is designed to allow choice • Can reuse classes from each layer in different architectures • Dependency Injection / AOP available within each layer as well as between architecturallayers
Working with Spring • No need to “code for Dependency Injection” • Follow good OO practice • The container exists to make the right thing easy to do • Merely avoid working against the container…
Helping Spring to help you • Program to interfaces, not classes • OO good practice emphasized by classic “Gang of Four” Design Patterns text • Concentrate on your domain and business logic • Defer wiring and enterprise service features • Follow agile process • TDD works!
Things to avoid • Pull configuration • Custom properties file lookups • Custom XML parsing • Singleton (anti)pattern • Excessive dependence on Spring APIs • There usually is a better way • Writing pointless code… • JNDI lookups • Client code aware of EJB APIs • Consider using Spring extension points in preference to building infrastructure from scratch
Spring is not about… • Replacing J2EE services • Provides a good alternative to EJB component model in most cases • J2EE != EJB • Throwing away your legacy code • Can introduce Spring incrementally • Can use Spring to simplify EJB-based projects
Spring is about… • Spring is about POJOs • The most complete realisation of the now universally accepted goal of POJO-based development • Spring is about reuse • Spring is about choice • Spring enables you to make choices • Spring offers something whatever your environment, from Java 1.3 and above • Spring is about consistency • Spring enables you to focus on your business domain • Question code that does not relate to your domain
The Spring Community • Apache 2.0 License • 23 developers • Over 7,000 users registered on Spring mailing lists and forums • Many more regularly use forums as guests • Helpful, courteous community • Numerous books, and more coming out • Professional Spring Development (Wrox) • Pro Spring (Rob Harrop)