JavaBeat

  • Home
  • Java
    • Java 7
    • Java 8
    • Java EE
    • Servlets
  • Spring Framework
    • Spring Tutorials
    • Spring 4 Tutorials
    • Spring Boot
  • JSF Tutorials
  • Most Popular
    • Binary Search Tree Traversal
    • Spring Batch Tutorial
    • AngularJS + Spring MVC
    • Spring Data JPA Tutorial
    • Packaging and Deploying Node.js
  • About Us
    • Join Us (JBC)
  • Privacy

Book Review : Spring in Action

November 11, 2012 by Krishna Srinivasan Leave a Comment

Spring in Action is the best selling book for the Spring framework. As the name says, it is full of action packed spring related examples and good explanation for the concepts. Let’s further review this book in detail to understand what is the content inside this book. This book is intended not only for the advanced developers with real experience on the spring framework, those who are looking to getting started on the spring framework too find it very useful. This book would be best suite you if you are looking to learn the concepts for implementing in your project.

The latest edition on this series, Spring in Action : Third Edition covers Spring 3.0 topics like most important aspects of Spring 3.0 including REST, remote services, messaging, Security, MVC, Web Flow, and more. If you are planning to buy, don’t buy the older version of the book. Go for the latest edition.  I have used this book for referring some important concepts, it is very useful for the developers to understand the difficult concepts in easier manner. The advantage of Action series by Manning is, they explain the concepts with very fundamentals, it helps the developers to easily grasp the knowledge. One must thank Manning for delivering great books!!

This book covers Spring framework core concept and all of the other modules from spring framework. I will review the chapter wise content, so that you will have an idea of what is inside the book. In the first chapter, Spring in Action talks about the basic concepts on core framework and explains about the Dependency Injection (DI), Aspect Oriented Programming (AOP), those two are the most important features of the spring framework. This book also delivers very good examples for each concept.

Second chapter explains the auto wiring concepts on the Dependency Injection (DI). It clearly explains how the beans are initiated and auto wired into other beans. If you have any idea on DI, you must understand the importance of DI in spring framework. These two chapters mainly focusing on the core of spring framework. Everyone must read the first two chapters to continue reading the rest of books.  Third chapter  explains about the Java config project of spring.

Fourth chapter is dedicated to the Aspect Oriented Programming (AOP) and various techniques used in the AOP. If you are familiar with spring framework earlier, spring framework is adapted AOP from the another framework AspectJ  and later AspectJ have joined the spring community. So, AOP becomes one of the mainstream feature in spring to choose for your project.

Rest of the chapters talks about the JDBC connections, transaction management, Spring MVC, Spring Web Flow, Spring Security, etc. Over all, Spring in Action covers the wide range of the spring topics for the developers need. I would recommend this book for the spring developers.If you have already used this book for your reference, please share your comments on this book. This would be helpful for the readers.

Buy : Spring in Action.

If you are looking for the further list of available books for spring framework, please refer our spring framework books recommendations. Hope this book review and list of books would help you to choose any one. If you are interested in receiving future java article from us, please subscribe here.

Filed Under: Book Review Tagged With: Book Review, Spring in Action

Book Review: Java Concurrency in Practice

July 1, 2012 by Mohamed Sanaulla Leave a Comment

Lot of us know that writing multi-threaded/concurrent applications in Java is not just about creating Thread objects and passing in Runnable implementations. Few of them mastered the art of concurrent programming and explored alternatives not only provided by Java but other languages like Scala, Groovy, Clojure. But quite a few of us have tried to venture into learning the nuisance of multi-threading, concurrency and never got close to even attempting to learn. And then we complain that Java doesn’t provide the constructs required for writing concurrent applications. The fact is that we never were aware of any good material which would help us to prepare and learn to build thread safe, concurrent applications.

I think your search should end at “Java Concurrency in Practice” by Brian Goetz and others. I should say I was fortunate to have got a copy of it and been able to read most of the chapters (I would dare not say all chapters, because few chapters in the advanced section were a bit difficult to comprehend). In this review I will throw some light on what the book covers, its salient features and who should read this book.

The book covers

  • basic multi-threaded concepts like thread safety, creating objects which are thread safe, synchronized blocks. There are lot of concepts explained here which are referred in future chapters.
  • the concurrency framework introduced in java.util.concurrent package as part of the Java 5 release.
  • different concepts like deadlock- detecting and diagnosing, performance and scalability concerns when it comes to mutli-threaded applications.
  • how to test concurrent applications, use tools like FindBugs and importance of code reviews in finding subtle issues.
  • some advanced topics like Atomic constructs in java.util.concurrent package, non-blocking synchronization.

Salient Features

  • the chapters have been organized such that it takes the readers from basic concepts and builds on that to advanced concepts.
  • each concept has been explained with code, though the code examples are not complete, they are just enough to understand what the authors want to convey.
  • the incomplete examples give some scope for readers to implement full fledged samples.
  • important concepts have been summarized where ever required

Who should read this book

  • If you are a beginner in Java, unaware of use of Threads, Runnable- then this book is not for you.
  • If you have programmed in Java, know how the use of Thread and Runnable and managing different threads is a pain- then you should pick this book to go beyond Thread and Runnable
  • If you are already familiar with java.util.concurrent package and all the things it offers, you should use this book to understand the advanced concepts like testing, understanding the performance and scalability aspects.

The book is heavy on concepts and requires lot of concentration from the readers part. Its very important to read the initial few chapters carefully and understand the basic concepts and lot of jargons which are used extensively through out the book.

Java Concurrency in Practice is intended for those who are aware of Thread concepts in Java and want to improve their concepts related to developing Multi-Threaded/Concurrent applications in Java and learn about the framework provided in Java for the same.

  • Buy Java Concurrency in Practice from Flipkart.com

Some of the concepts explained in the book have been captured as blog posts:

  • Using ExecuterService framework to develop applications which support concurrent execution of tasks. More details can be read in the post here.
  • Using BlockingQueue to solve the Producer and consumer problem. More details can be found here.

Filed Under: Book Review Tagged With: Book Review, java concurrency, Java Concurrency in Practice

RESTful Java Web Services

December 8, 2009 by Krishna Srinivasan Leave a Comment

RESTful Java Web ServicesThis article is sample chapter for the book RESTful Java Web Services. If you’re already familiar with REST theory, but are new to RESTful Java web services, and want to use the Java technology stack together with Java RESTful frameworks to create robust web services, this is the book for you.

also read:

  • What is UDDI?
  • Apache Axis 2 Web Services
  • RESTFul Java Web Services

This book is a guide for developing RESTful web services using Java and the most popular RESTful Java frameworks available today. This book covers the theory of REST, practical coding examples for RESTful clients, a practical outline of the RESTful design, and a complete implementation of a non-trivial web service using the frameworks Jersey’s JAX-RS, Restlet’s Lightweight REST, JBoss’s JAX-RS RESTEasy, and Struts 2 with the REST plugin.

We cover each framework in detail so you can compare their strengths and weaknesses. This coverage will also provide you with enough knowledge to begin developing your own web services after the first reading.

  • Spring RESTFul Services

The RESTful development process follows traditional development paradigms. However, with RESTful web services, we need to analyze the resource requirements first, design the representation for our resources second, identify the URIs third, and, lastly, worry about implementation technologies.

Throughout this book we’ve talked about creating web services that are noun dependent as opposed to verb dependent. In this chapter we’ll look at what that means in terms of the design process. For this, we’ll design a blogging application, but we’ll leave the implementation for later chapters. Our sample application is a micro-blogging web service (similar to Twitter), where users create accounts and then post entries.

Finally, while designing our application, we’ll define a set of steps that can be applied to designing any software system that needs to be deployed as a RESTful web service.

Designing a RESTful web service

Designing RESTful web services is not different from designing traditional web applications. We still have business requirements, we still have users who want to do things with data, and we still have hardware constraints and software architectures to deal with. The main difference, however, is that we look at the requirements to tease out resources and forget about specific actions to be taken on these resources.

We can think of RESTful web service design as being similar to Object Oriented Design (OOD). In OOD, we try to identify objects from the data we want to represent together with the actions that an object can have. But the similarities end at the data structure definition, because with RESTful web services we already have specific calls that are part of the protocol itself.The underlying RESTful web service design principles can be summarized in the following four steps:

  1. Requirements gathering—this step is similar to traditional software requirement gathering practices.
  2. Resource identification—this step is similar to OOD where we identify objects, but we don’t worry about messaging between objects.
  3. Resource representation definition—because we exchange representation between clients and servers, we should define what kind of representation we need to use. Typically, we use XML, but JSON has gained popularity. That’s not to say that we can’t use any other form of resource representation—on the contrary, we could use XHTML or any other form of binary representation, though we let the requirements guide our choices.
  4. URI definition—with resources in place, we need to define the API, which consists of URIs for clients and servers to exchange resources’ representations.

This design process is not static. These are iterative steps that gravitate around resources. Let’s say that during the URI definition step we discover that one of the URI’s responses is not covered in one of the resources we have identified. Then we go back to define a suitable resource. In most cases, however, we find that the resources that we already have cover most of our needs, and we just have to combine existing resources into a meta-resource to take care of the new requirement.

Requirements of sample web service

The RESTful web service we design in this chapter is a social networking web application similar to Twitter.

Throughout this book, we follow an OOD process mixed with an agile philosophy for designing and coding our applications. This means that we create just enough documentation to be useful, but not so much that we spend an inordinate amount of time deciphering it during our implementation phase.

As with any application, we begin by listing the main business requirements, for which we have the following use cases (these are the main functions of our application):

  • A web user creates an account with a username and a password (creating an account means that the user is now registered).
  • Registered users post blog entries to their accounts. We limit messages to 140 characters.
  • Registered and non-registered users view all blog entries.
  • Registered and non-registered users view user profiles.
  • Registered users update their user profiles, for example, users update their password.
  • Registered and non-registered users search for terms in all blog entries.

However simple this example may be, social networking sites work on these same principles: users sign up for accounts to post personal updates or information. Our intention here, though, is not to fully replicate Twitter or to fully create a social networking application. What we are trying to outline is a set of requirements that will test our understanding of RESTful web services design and implementation.

The core value of social networking sites lies in the ability to connect to multiple users who connect with us, and the value is derived from what the connections mean within the community, because of the tendency of users following people with similar interests. For example, the connections between users create targeted distribution networks.

The connections between users create random graphs in the graph theory sense, where nodes are users and edges are connections between users. This is what is referred to as the social graph.

Resource identification

Out of the use cases listed above, we now need to define the service’s resources. From reading the requirements we see that we need users and messages. Users appear in two ways: a single user and a list of users. Additionally, users have the ability to post blog entries in the form of messages of no more than 140 characters. This means that we need resources for a single message and a list of messages. In sum, we identify the following resources:

  1. User
  2. List of users
  3. Message
  4. List of messages

Representation definition

As we discussed in our introduction to RESTful web services, a representation is a temporal mapping of a resource at the time of a request. Furthermore, a representation is transmitted between clients and servers over HTTP. Because of HTTP’s fl exibility, any binary stream can be transferred. Nevertheless, we don’t recommend choosing just any type of binary representation that requires special code or libraries to consume. We recommend using primarily XML and JSON structures, remembering, of course, that the requirements of the problem we’re solving dictate what representation types we must provide.

A well-designed RESTful web service needs to provide multiple resource representations. We can’t assume that only web browsers will be accessing our public APIs or that only the one type of client we identified in our requirement gathering process will use our services.

What are the options available, then?

Again, arriving at the ideal representation format is a matter of the design process. We need to take into account what the service is doing and what clients will be using the resources for. The safest representation format is therefore XML. This is what web services are known for: transferring XML streams over web transport protocols. More important, most programming languages already have libraries available to parse XML streams.

Finally, we need to account for linkability of representations. Linkability of representation means that the web services provide for resource discoverability, such that resources link to other resources (what’s currently being referred to as HATEOS or Hypermedia As The Engine Of State transfer). For example, our URI for a list of users returns a structure of users with each element in the list having a direct URI to each element in the service (a link to a user).

XML representations

From our analysis, we identified two types of resources: users and messages. As part of the heuristics we outlined earlier, we need to define what our representation will look like. The following representations are the structures that we will have to implement when we actually code the web service.

Users

We first define a user representation as follows:

[code lang=”xml”]
<user>
<username></username>
<password></password>
<link></link>
</user>
[/code]

As part of a user resource, we store only a username and a password. The username is unique in the context of our system and is used to uniquely identify each user. The link element, which points back to the web service, is either assigned when the resource is created or a representation is built for transport (for our sample service, we let the backend create the link).

We now define a list of users as follows:

[code lang=”xml”] <users>
<count></count>
<link></link>
<user>
<username></username>
<password></password>
<link></link>
</user>
…
<user>
<username></username>
<password></password>
<link></link>
</user>
</users>[/code]

This XML structure declares a list of users stored in an XML element . We use ellipses or … to show that we can have more than one user in the list.

We can see here the linkability concept at play: with a list of users we can drill down to individual users using the link element’s value.

Messages

We first define a single blog entry or message as follows:

[code lang=”xml”] <message>
<messageID></messageID>
<content></content>
<link></link>
<user>
<username></username>
<password></password>
<link></link>
</user>
</message>[/code]

A message needs a message id, the body of the message (the content element), and the user who posted the message. Note that depending on what we are doing with the message, we don’t pass all the resource’s information back and forth. For example, when we are creating a message at the client layer, we don’t know what the value for messageID is. Therefore, we still need to pass the message structure to the service, but our web service will know that any messageID value needs to be ignored, because, in our case, it will be created by the storage layer.

Finally, we define a list of messages as follows:

[code lang=”xml”] <messages>
<count></count>
<link></link>
<message>
<messageID></messageID>
<content></content>
<link></link>
<user>
<username></username>
<password></password>
<link></link>
</user>
</message>
…
<message>
<messageID></messageID>
<content></content>
<link></link>
<user>
<username></username>
<password></password>
<link></link>
</user>
</message>
</messages>[/code]

This XML structure holds a collection of messages, and each message holds the user who posted the message.

We use the XML representation type for input and output. Input in this case means that we send a resource representation to create and update the resources at the web service layer in the form of an XML object. Output means that a client requests an XML representation of a resource.

JSON representations

We use the same key names for our JSON representation, and we still have only two types of resources: users and messages. Again, these structures are our specification of what we need to return for each request.

Users

We define a user representation as follows:

[code lang=”html”] {"user":{"username":"john", "password":"password", "link":"/users/
john"}}[/code]

And we define a list of users as follows (we use the … characters to show that there is more than one user in the array):

[code lang=”html”] {"users-result":{"count":"6", "users":[{"username":"john",
"password":"password", "link":"/users/john"}, …,{"username":"jane",
"password":"password", "link":"/users/jane"}]}}[/code]

The array for all users as a JSON structure, looks as follows:

[code lang=”html”] "users":[{"username":"john", "password":"password", "link":"/users/
john"}, …,{"username":"jane", "password":"password", "link":"/users/
jane"}][/code]

Once the JSON response has been evaluated with the JavaScript eval() function, similar to what we did in Chapters 2 and 3, we can then access any of the values in the structure. For example, if we need the user name of the first element on the array, we use users-result.users[0].username.

Messages

We now define a message representation as follows:

[code lang=”html”] {"message":{"messageID":"some-id", "content":"some content",
"link":"/messages/some-id", "user":{"user":{"username":"john",
"password":"password", "link":"/users/john"}}}[/code]

And a list of messages as follows:

[code lang=”html”] {"messages-result":{"count":"6", "link":"/messages",
"messages":[{"messageID":"some-id", "content":"some content",
"link":"/messages/some-id", "user":{"username":"john",
"password":"password", "link":"/users/john"}}, …,{"messageID":"someid2",
"content":"some content", "link":"/messages/some-id2",
"user":{"username":"jane", "password":"password", "link":"/users/
jane"}}]}}[/code]

Each message element in the array has a user structure embedded as follows:

[code lang=”html”] {"messageID":"some-id", "content":"some content",
"user":{"username":"john", "password":"password", "link":"/users/
john"}}[/code]

Once the JSON response has been evaluated with the JavaScript eval() function, we can then access the first element on the list with messages-result.messages[0]. content; if we want to get the user name of the user who posted the message, we access the value with messages-result.messages[0].user.username.

Note that during implementation we’ll use JSON representations only as response streams. This means that we won’t use JSON structures to create or update resources at the web service layer. Although we could use XML and JSON to update resources at the service layer, we’ll omit JSON for the sake of brevity.

URI definition

The next step involves the definition of URIs. This is a crucial step, as the URIs define our API and it’s likely that we want to make our web service public.

We strive to make our APIs logical, hierarchical, and as permanent as we can. We must emphasize these three tenets, as we may have many developers depending on the services we make available. Therefore, a good API is one that doesn’t change too often and is unambiguous to use. Furthermore, the idea of RESTful APIs is that we maintain URI uniqueness and reliability of service. (For a complete discussion about this topic, see http://www.w3.org/Provider/Style/URI.)

The first thing we need is a web address. In our case, we assume that we’re using our development machine running on http://localhost:8080/.

It’s important to distinguish between a web service and a web application:
we use web services to implement web applications, and web services can be, and are recommended to be, independent of web applications. What’s more, web applications are meant to be consumed by humans as opposed to web services that are intended for machine consumption.

For example, a RESTful API could live under http://api. restfuljava.com/ and a web application using the API could ive under http://restfuljava.com/. Both the API and the web application should be running on independent hardware for performance reasons, but when we get to implement our sample service we run everything on the same server.

The nomenclature of RESTful URIs falls under the topic of URI templates and the following conventions are widely used. First, for items or identifiers that don’t change, we find the keyword to be part of the actual URI—for instance, we use users to be the URI for a list of all users. Second, we use keys or dynamic keywords to be enclosed in { and }. Applying these conventions, our URI list for users looks as follows:

  • http://localhost:8080/users—with the GET method, this URI returns a list of all users; with the POST method, we create a new user and the payload is a user’s XML representation; we don’t support the PUT method; finally, we don’t support the DELETE method for an entire list of users
  • http://localhost:8080/users/{username}—with the GET method, this URI returns a representation of a user with a unique identifier username; with the PUT method, it updates a user; and, with the DELETE method, it deletes a user.

And for messages, our URI list looks as follows:

  • http://localhost:8080/messages—with the GET method, this URI returns a list of all messages from all users; with the POST method, it creates a new message, with the message’s XML representation as the payload of the request
  • http://localhost:8080/messages/{messageID}—with the GET method, this URI returns a representation for a message with the unique identifier messageID; with the DELETE method, it deletes a message; and we don’t support the POST or PUT methods
  • http://localhost:8080/messages/users/{username}—with the GET method, this URI returns a list of all message for a user with identifier username; no POST, PUT, or DELETE methods are supported

At the time of this writing, the URI Template specification is still under review. For more information, see http://tools.ietf.org/html/draft-gregorio-uritemplate-03.

Executing logic with RESTful URIs

A question arises when designing RESTful web services that has to do with executing code at the server level. Specifically, how do we execute logic if we limit our client/server interactions to only four CRUD-like calls (POST, GET, PUT, and DELETE)? For this we need to introduce URIs that execute logic on the server,remembering that responses must be in the form of resource representations. In other words, we avoid any RPC style calls and concentrate on the resources only.

For our web service, we only offer the ability of searching for a term or a phrase in the blog entries. For example, any user can search for the term “programming” or” software development” using the following URI (note that the URI pattern is arbitrary and you can choose whatever makes sense for the service you are developing):

[code] http://localhost:8080/messages/search/{search_item}[/code]

This URI returns a list of messages that contain the word or words search_item—this is strictly a GET method call and no POST, PUT, or DELETE method is supported.

Using URIs to request representation types

A RESTful web service is one that adheres to all the constraints we outlined in Chapter 1, RESTful Architectures. However, we have encountered APIs that don’t strictly adhere to every constraint. For example, requesting representation types via URIs is something we saw with Twitter’s API. We requested three different types of representations with the URI ttp://twitter.com/statuses/public_timeline. {xml, json, rss}.

We said that this is not technically a RESTful web service request, because we don’t use the communication protocol—HTTP headers—to tell the service what kind of representation to get. Even though this is not a RESTful web service, it still works. Nevertheless, the API may be open to interpretation. For example, what does it mean to send an HTTP GET request to the URI http://twitter.com/statuses/
public_timeline.json with an HTTP Accept header value of application/xml? Do we get a JSON representation or an XML epresentation? A properly designed RESTful web service has to adhere to all REST constraints, and using the protocol to negotiate representations is part of being RESTful.

Creating a properly defined RESTful web service, however, ensures that there are no misunderstandings on how to use such services. For example, setting the HTTP method type to GET with an appropriate Accept header value makes it clear that we are requesting a resource of a specific type. In the end, you, as a developer or software architect, need to make a decision as to which style will benefit your users the most.

Using this representation request style is a design decision that facilitates—it can be argued—the writing of clients. For instance, the majority of public APIs are read only, so using a straight HTTP GET request with the type of representation embedded in the URI is easier than instantiating a full HTTP request and modifying the HTTP header Accept each time. Note that neither is hard to implement; however, with the former, we save a couple of lines of code at the client layer. Again, it’s a matter of choice.

Our sample web service is a canonical application, thus we don’t deviate from any of the constraints. This means that we use the HTTP protocol to request a preferred resource representation and not the URI style described in this section.[/code]

Summary

  • Invoking RESTful Web Service using API in java.net and GSON 
  • Introduction to Spring REST Services
  • RESTEasy Hello World Example

As we’ve seen, the RESTful design process is resource centric. In addition, we have no arbitrary actions executing on the data—we have HTTP method calls that exchange representations using clearly defined URIs. The steps to arrive at a web service that adheres to all REST constraints are similar to traditional web application design. So we can still use all our traditional requirement gathering techniques, but tweak the process to account for proper design of usable URIs and consumable representations.

Now that we have our social networking web service specification defined together with a set of RESTful design principles, the next step is implementation. We have four different REST frameworks in the menu, so in the next chapter we begin with Jersey, which is the reference implementation of the Java API for RESTful Web Services Specification, more commonly known as JAX-RS.

Filed Under: WebServices Tagged With: Book Review, REST

Aspect Oriented Programming (AOP) in Spring 2.5

February 20, 2009 by Krishna Srinivasan Leave a Comment

This article publishes the book excerpt from the book Spring 2.5 Aspect Oriented Programming by Massimiliano Dessi.The following are the list of chapters in the book and brief description inside each chapters. If you are interested in receiving the future articles on book reviews and latest news on Java, please subscribe here.

Chapter 1 introduces the ideas that led to Aspect-Oriented Programming. An overview of main concepts of AOP is used to describe components and features provided by Spring AOP, while a set of concise yet clear examples lets the reader discover what can actually be done with AOP.

Chapter 2 describes in detail the fundamentals of AOP in Spring, presenting interfaces and classes introduced in early 1.x versions of the framework. This chapter shows how to use AOP programmatically, to let the reader discover the basis of Spring AOP and the components that implement Aspect-Oriented Programming in Spring.

also read:

  • Spring Framework Interview Questions
  • Introduction to Spring Framework
  • Spring and Hibernate Integration
  • Spring Framework Books (recommended)

Chapter 3 explains how the weaving of AOP components is done using the proxy pattern and JDK or CGLIB implementations. It describes the purpose of proxies and how to use them effectively. Some practical examples show how to use the proxies programmatically, with annotations and with XML; they explain the ProxyFactoryBean and how to make the programmer’s work easier with AutoProxy. The chapter describes also some smart techniques on target sources.

Chapter 4 explains how Spring AOP is supported by AspectJ. Configuration activity is made simpler, more flexible and more powerful, thanks to annotations and the syntax of AspectJ on pointcuts (without which those costructs would not be available). All examples show how to use AspectJ with both annotations and XML. The chapter contains practical recipes for specific cases, such as the injection of dependencies on domain objects, the management of aspects’ priority, the use of different life cycles for Aspects and how to use Load Time Weaving. The chapter ends with some strategies on
how to choose different AOP approaches to fulfil specific requirements.

Chapter 5 describes the design alternatives that can be implemented using AOP. These alternatives are solutions for common requirements: concurrency, caching, and security. Using AOP, they can be achieved in a very elegant and easy way, being at the same time totally transparent for the system where they are applied.

spring-2-5-aspect-oriented-programming-275x275-imad9tahmcerhnfg

Chapter 6 introduces Domain-Driven Development as a alternative way to design applications. The prototype example presented in this chapter is a typical Three-Layer application, where DDD is used for design and AOP is used to inject the dependencies on domain objects. iBatis is used for persistence to the database.

Chapter 7 completes the prototype application started in Chapter 6, showing the application layer and the user interface. The latter is implemented with Spring MVC using annotations. Integration and unit tests are used to verify the correctness of the classes; DBUnit is used to test persistence classes, while some Mock classes are used to test the UI. The chapter contains the configurations for the prototype infrastructure, including autentication and authorization with Spring Security and the JUnit 4.5 test suite.

Chapter 8 describes the development tools needed to include Spring AOP and AspectJ in the Eclipse IDE. The reader can find here detailed istructions on how to configure Eclipse with the plug-ins for Spring and for the AspectJ Development Tool, and how to install the PostgreSQL database and the Apache Tomcat servlet engine. All installation procedures are described for the three main operating systems: Ubuntu Linux, Apple Mac OS X, and
Microsoft Windows XP.

Design with AOP in Spring 2.5

In this chapter, we’re going to examine some design decisions that are important for building better applications. In these design decisions, the AOP plays a signifi cant role because it provides smart solutions to common crosscutting problems.

  • Spring Aspect Oriented Programming (AOP) 

We will look at the following AOP design solutions:

  • Concurrency with AOP
  • Transparent caching with AOP
  • Security with AOP

Designing and implementing an enterprise Java application means not only dealing with the application core business and architecture, but also with some typical enterprise requirements.

We have to defi ne how the application manages concurrency so that the application is robust and does not suffer too badly from an increase in the number of requests. We have to defi ne the caching strategies for the application because we don’t want CPU- or data-intensive operations to be executed over and over.

We have to defi ne roles and profi les, applying security policies and restricting access to application parts, because different kinds of users will probably have different rights and permissions. All these issues require writing additional code that clutters our application business code and reduces its modularity and maintainability.

But we have a choice. We can design our enterprise Java application keeping AOP in mind. This will help us to concentrate on our actual business code, taking away all the infrastructure issues that can otherwise be expressed as crosscutting concerns. This chapter will introduce such issues, and will show how to design and implement solutions to them with Spring 2.5 AOP support.

Concurrency with AOP

Concurrency is the system’s ability to act with several requests simultaneously, such a way that threads don’t corrupt the state of objects when they gain access at the same time.

A number of good books have been written on this subject, such as Concurrent Programming in Java and Java Concurrency in Practice. They deserve much attention, since concurrency is an aspect that’s hard to understand, and not immediately visible to developers. Problems in the area of concurrency are hard to reproduce. However, it’s important to keep concurrency in mind to assure that the application is robust regardless of the number of users it will serve.

If we don’t take into account concurrency and document when and how the problems of concurrency are considered, we will build an application taking some risks by supposing that the CPU will never simultaneously schedule processes on parts of our application that are not thread-safe.

To ensure the building of robust and scalable systems, we use proper patterns. There are JDK packages just for concurrency. They are in the java.util.concurrent package, a result of JSR-166.

One of these patterns is the read-write lock pattern, which consists of is the interface java.util.concurrent.locks.ReadWriteLock and some implementations, one of which is ReentrantReadWriteLock.

The goal of ReadWriteLock is to allow the reading of an object from a virtually endless number of threads, while only one thread at a time can modify it. In this way, the state of the object can never be corrupted because threads reading the object’s state will always read up-to-date data, and the thread modifying the state of the object in question will be able to act without the possibility of the object’s state being corrupted. Another necessary feature is that the result of a thread’s action can be visible to the other threads. The behavior is the same as we could have achieved using synchronized, but when using a read-write lock we are explicitly synchronizing the actions, whereas with synchronized synchronization is implicit. Now let’s see an example of ReadWriteLock on the BankAccountThreadSafe object.

Before the read operation that needs to be safe, we set the read lock. After the read operation, we release the read lock.

Before the write operation that needs to be safe, we set the write lock. After a state modifi cation, we release the write lock.

[code lang=”java”]
package org.springAOP.chapter.five.concurrent;
import java.util.Date;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public final class BankAccountThreadSafe {
public BankAccountThreadSafe(Integer id) {
this.id = id;
balance = new Float(0);
startDate = new Date();
}
public BankAccountThreadSafe(Integer id, Float balance) {
this.id = id;
this.balance = balance;
startDate = new Date();
}
public BankAccountThreadSafe(Integer id, Float balance, Date start)
{
this.id = id;
this.balance = balance;
this.startDate = start;
}
public boolean debitOperation(Float debit) {
wLock.lock();
try {
float balance = getBalance();
if (balance &lt; debit) {
return false;
} else {
setBalance(balance – debit);
return true;
}
} finally {
wLock.unlock();
}
}
public void creditOperation(Float credit) {
wLock.lock();
try {
setBalance(getBalance() + credit);
} finally {
wLock.unlock();
}
}
private void setBalance(Float balance) {
wLock.lock();
try {
balance = balance;
} finally {
wLock.unlock();
}
}
public Float getBalance() {
rLock.lock();
try {
return balance;
} finally {
rLock.unlock();
}
}
public Integer getId() {
return id;
}
public Date getStartDate() {
return (Date) startDate.clone();
}
…
private Float balance;
private final Integer id;
private final Date startDate;
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock rLock = lock.readLock();
private final Lock wLock = lock.writeLock();
}
[/code]

BankAccountThreadSafe is a class that doesn’t allow a bank account to be overdrawn (that is, have a negative balance), and it’s an example of a thread-safe class. The final fi elds are set in the constructors, hence implicitly thread-safe. The balance fi eld, on the other hand, is managed in a thread-safe way by the setBalance, getBalance, creditOperation, and debitOperation methods.

In other words, this clas s is correctly programmed, concurrency-wise. The problem is that wherever we would like to have those characteristics, we have to write the same code (especially the finally block containing the lock’s release). We can solve that by writing an aspect that carries out that task for us.
A state modification is execution(void com.mycompany.BankAccount.set*(*))
A safe read is execution(* com.mycompany.BankAccount.getBalance())
[code lang=”java”]
package org.springAOP.chapter.five.concurrent;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.AspectJ.lang.annotation.After;
import org.AspectJ.lang.annotation.Aspect;
import org.AspectJ.lang.annotation.Before;
import org.AspectJ.lang.annotation.Pointcut;
@Aspect
public class BankAccountAspect {
/*pointcuts*/
@Pointcut(
"execution(* org.springAOP.chapter.five.concurrent.BankAccount.
getBalance())")
public void safeRead(){}
@Pointcut(
"execution(* org.springAOP.chapter.five.concurrent.BankAccount.
set*(*))")
public void stateModification(){}
@Pointcut(
"execution(* org.springAOP.chapter.five.concurrent.BankAccount.
getId())")
public void getId(){}
@Pointcut("execution(* org.springAOP.chapter.five.concurrent.
BankAccount.getStartDate()))
public void getStartDate(){}
/*advices*/
@Before("safeRead()")
public void beforeSafeRead() {
rLock.lock();
}
@After("safeRead()")
public void afterSafeRead() {
rLock.unlock();
}
@Before("stateModification()")
public void beforeSafeWrite() {
wLock.lock();
}
@After("stateModification()")
public void afterSafeWrite() {
wLock.unlock();
}
private final ReadWriteLock lock = new
ReentrantReadWriteLock();
private final Lock rLock = lock.readLock();
private final Lock wLock = lock.writeLock();
}
[/code]

The BankAccountAspect class applies the crosscutting functionality. In this case, the functionality is calling the lock and unlock methods on the ReadLock and the WriteLock. The before methods apply the locks with the @Before annotation, while the after methods release the locks as if they were in the fi nal block, with the @After annotation that is always executed (an after-fi nally advice). In this way the BankAccount class can become much easier, clearer, and briefer. It doesn’t need any indication that it can be executed in a thread-safe manner.

[code lang=”java”]
package org.springAOP.chapter.five.concurrent;
import java.util.Date;
public class BankAccount {
public BankAccount(Integer id) {
this.id = id;
this.balance = new Float(0);
this.startDate = new Date();
}
public BankAccount(Integer id, Float balance) {
this.id = id;
this.balance = balance;
this.startDate = new Date();
}
public BankAccount(Integer id, Float balance, Date start) {
this.id = id;
this.balance = balance;
this.startDate = start;
}
public boolean debitOperation(Float debit) {
float balance = getBalance();
if (balance &lt; debit) {
return false;
} else {
setBalance(balance – debit);
return true;
}
}
public void creditOperation(Float credit) {
setBalance(getBalance() + credit);
}
private void setBalance(Float balance) {
this.balance = balance;
}
public Float getBalance() {
return balance;
}
public Integer getId() {
return id;
}
public Date getStartDate() {
return (Date) startDate.clone();
}
private Float balance;
private final Integer id;
private final Date startDate;
}
[/code]

Another good design choice, together with the use of ReadWriteLock when necessary, is using objects that once built are immutable, and therefore, not
corruptible and can be easily shared between threads.

Transparent caching with AOP

Often, the objects that compose applications perform the same operations with the same arguments and obtain the same results. Sometimes, these operations are costly in terms of CPU usage, or may be there is a lot of I/O going on while executing those operations.

To get better results in terms of speed and resources used, it’s suggested to use a cache. We can store in it the results corresponding to the methods’ invocations as key-value pairs: method and arguments as key and return object as value.

Once you decide to use a cache you’re just halfway. In fact, you must decide which part of the application is going to use the cache. Let’s think about a web application backed by a database. Such a web application usually involves Data Access Objects (DAOs), which access the relational database. Such objects are usually a bottleneck in the application as there is a lot of I/O going on. In other words, a cache can be used there.

The cache can also be used by the business layer that has already aggregated and elaborated data retrieved from repositories, or it can be used by the presentation layer putting formatted presentation templates in the cache, or even by the authentication system that keeps roles according to an authenticated username.

There are almost no limits as to how you can optimize an application and make it faster. The only price you pay is having RAM to dedicate the objects that are to be kept in memory, besides paying attention to the rules on how to manage the life of the objects in cache.

After these preliminary remarks, using a cache could seem common and obvious. A cache essentially acts as a hash into which key-value pairs are put. The keys are used to retrieve objects from the cache. Caching usually has confi guration parameters that allow you to change its behavior.

Now let’s have a look at an example with ehcache (http://ehcache.sourceforge. net). First of all let’s configure it with the name methodCache so that we have at the most 1000 objects. The objects are inactive for a maximum of fi ve minutes, with a maximum life of 10 minutes. If the objects count is over 1000, ehcache saves them on the filesystem, in java.io.tmpdir.

[code lang=”java”]
<ehcache>
…
<diskStore path="java.io.tmpdir"/>
….
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
/>
…
<cache name="methodCache"
maxElementsInMemory="1000"
eternal="false"
overflowToDisk="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
/>
</ehcache>
[/code]

Now let’s create a CacheAspect. Let’s defi ne the cacheObject to which the ProceedingJoinPoint is passed. Let’s recover an unambiguous key from the
ProceedingJoinPoint with the method getCacheKey. We will use this key to put the objects into the cache and to recover them.

Once we have obtained the key, we ask to cache the Element with the instruction cache.get(cacheKey). The Element has to be evaluated because it may be null if the cache didn’t fi nd an Element with the passed cacheKey.

If the Element is null, advice invokes the method proceed(), and puts in the cache the Element with the key corresponding to the invocation. Otherwise, if the Element recovered from the cache is not null, the method isn’t invoked on the target class, and the value taken from the cache is returned to the caller.

[code lang=”java”]
package org.springaop.chapter.five.cache;
import it.springaop.utils.Constants;
import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
public class CacheAspect {
public Object cacheObject(ProceedingJoinPoint pjp) throws Throwable
{
Object result;
String cacheKey = getCacheKey(pjp);
Element element = (Element) cache.get(cacheKey);
logger.info(new StringBuilder("CacheAspect invoke:").append("\n
get:")
.append(cacheKey).append(" value:").append(element).
toString());
if (element == null) {
result = pjp.proceed();
element = new Element(cacheKey, result);
cache.put(element);
logger.info(new StringBuilder("\n put:").append(cacheKey).
append(
" value:").append(result).toString());
}
return element.getValue();
}
public void flush() {
cache.flush();
}
private String getCacheKey(ProceedingJoinPoint pjp) {
String targetName = pjp.getTarget().getClass().getSimpleName();
String methodName = pjp.getSignature().getName();
Object[] arguments = pjp.getArgs();
StringBuilder sb = new StringBuilder();
sb.append(targetName).append(".").append(methodName);
if ((arguments != null) &amp;&amp; (arguments.length != 0)) {
for (int i = 0; i &lt; arguments.length; i++) {
sb.append(".").append(arguments[i]);
}
}
return sb.toString();
}
public void setCache(Cache cache) {
this.cache = cache;
}
private Cache cache;
private Logger logger = Logger.getLogger(Constants.LOG_NAME);
}
Here is applicationContext.xml :
<beans xmlns=»http://www.springframework.org/schema/beans»
xmlns:xsi=»http://www.w3.org/2001/XMLSchema-instance»
xmlns:aop=»http://www.springframework.org/schema/aop»
xsi:schemaLocation=»http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-2.5.xsd»> …
<bean id="rockerCacheAspect" >
<property name="cache">
<bean id="bandCache" parent="cache">
<property name="cacheName" value="methodCache" />
</bean>
</property>
</bean>
<!– CACHE config –>
<bean id="cache" abstract="true"
class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager" ref="cacheManager" />
</bean>
<bean id="cacheManager"
class="org.springframework.cache.ehcache.
EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:org/springaop/
chapter/five/cache/ehcache.xml" />
</bean>
…
</beans>
[/code]

The idea about the caching aspect is to avoid repetition in our code base and have a consistent strategy for identifying objects (for example using the hash code of an object) so as to prevent objects from ending up in the cache twice.

Employing an around advice, we can use the cache to make the method invocations return the cached result of a previous invocation of the same method in a totally transparent way. In fact, to the methods of the classes defi ned in the interception rules in pointcuts will be given back the return values drawn from the cache or, if these are not present, they will be invoked and inserted in the cache. In this way, the classes and methods don’t have any knowledge of obtaining values retrieved from the cache. Let’s define the pointcut that intercepts the methods of the class DummyClass.

[code lang=”java”]
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
…
<aop:config>
<!– Pointcuts –>
<aop:pointcut id="readOperation" expression=
"execution(* org.springaop.chapter.five.cache.DummyClass.get*(..))"
/>
<aop:pointcut id="exitOperation" expression=
"execution(void org.springaop.chapter.five.cache.DummyClass.exit())"
/>
<!– Aspects –>
<aop:aspect id="dummyCacheAspect" ref="rockerCacheAspect">
<aop:around pointcut-ref="readOperation" method="cacheObject" />
<aop:after pointcut-ref="exitOperation" method="flush" />
</aop:aspect>
</aop:config>
…
</beans>
Class DummyClass used to check the cache’s working:
package org.springaop.chapter.five.cache;
public class DummyClass {
public String getFooFighters(){
return "My hero";
}
public String getHives(String year){
if(year.equals("2004")){
return "Walk idiot walk !";}else{
return "Abra Cadaver";
}
}
public String getDandyWarhols(){
return "Ride";
}
public void exit(){
System.out.println("The end.");
}
}
Here is ApplicationContext.xml complete:
<beans xmlns=»http://www.springframework.org/schema/beans»
xmlns:xsi=»http://www.w3.org/2001/XMLSchema-instance»
xmlns:aop=»http://www.springframework.org/schema/aop»
xsi:schemaLocation=»http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-2.5.xsd»>

<bean id="dummy"/>
<aop:config>
<!– Pointcuts –>
<aop:pointcut id="readOperation"
expression="execution(* org.springaop.chapter.five.cache.
DummyClass.get*(..))" />
<aop:pointcut id="exitOperation"
expression="execution(void org.springaop.chapter.five.
cache.DummyClass.exit())" />
<!– Aspects –>
<aop:aspect id="dummyCacheAspect" ref="rockerCacheAspect">
<aop:around pointcut-ref="readOperation" method="cacheObject"
/>
<aop:after pointcut-ref="exitOperation" method="flush" />
</aop:aspect>
</aop:config>
<bean id="rockerCacheAspect" >
<property name="cache">
<bean id="bandCache" parent="cache">
<property name="cacheName" value="methodCache" />
</bean>
</property>
</bean>
<!– CACHE config –>
<bean id="cache" abstract="true"
class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager" ref="cacheManager" />
</bean>
<bean id="cacheManager"
class="org.springframework.cache.ehcache.
EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:org/springaop/
chapter/five/cache/ehcache.xml" />
</bean>
</beans>
[/code]

ApplicationContext contains the following beans:

  • The dummy bean, used to test the cache’s working.
  • The readOperation and exitOperation pointcuts.
  • The dummyCacheAspect aspect, with around and after advices.
  • The rockerCacheAspect, which is the implementation of the aspect class that contains the logic of recovery from and insertion into the cache.
  • The cache bean, which is an EhCacheFactoryBean.
  • The cacheManager bean, which is an EhCacheManagerFactoryBean.

Here is the test class:

[code lang=”java”]
package org.springaop.chapter.five.cache;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.
ClassPathXmlApplicationContext;
public class CacheTest {
public static void main(String[] args){
String[] paths = { "org/springaop/chapter/five/cache/
applicationContext.xml" };
ApplicationContext ctx = new ClassPathXmlApplicationContext
(paths);
DummyClass dummy = (DummyClass) ctx.getBean("dummy");
dummy.getFooFighters();
dummy.getHives("2004");
dummy.getDandyWarhols();
dummy.getFooFighters();
dummy.getHives("2004");
dummy.getDandyWarhols();
dummy.exit();
}
}
[/code]

Security with AOP

  • Spring security 3.0 

Security is one of the most important elements of an application. The word “security” covers two concepts:

Authentication is the verifi cation’s process of a principal’s identity; a principal is typically a user. A principal in order to be authenticated
provides a credential that is the password.

Authorization, on the other hand, is the process of granting authorities, which are usually roles, to an authenticated user.

Once a user is authenticated and has roles, he or she can work on the application and perform the actions permitted by an access control list, which according to the user’s roles allows certain operations.

Before Spring Security, the rules of who can do what were usually implemented using custom code and an in-house framework, or using JAAS. Usually, the first type of implementation was a consequence of the second type’s diffi culty.

Unfortunately, though custom-type security fi ts its purposes, it lacks in its main aim. This is because it’s safer to employ a much-used framework that is constantly updated and corrects security problems, rather than having an in-house framework that might be barely tested. Beside these considerations, which should be carefully take into account, defi ning and applying security rules without AOP means causing code tangling and code scattering.

In fact, AOP applied to security solves most of the common practical problems concerning security. In order to solve them we use Spring Security 2.0.x (formerly Acegi Security System for Spring), confi guring it properly to carry out most of the work according to the application’s needs. We will see its confi guration in Chapter 7. Now let’s look just at some parts where AOP intervenes in its confi guration.

For now, we will not deal with the authentications and roles attribution. Instead, we will start from the point at which the decision is taken to authorize a user and to provide him or her with roles to access a certain resource. Taking an actual decision whether or not to allow the user (based on its roles) gain access to the secure resource is the responsibility of the access decision manager.

An access decision manager implements the AccessDecisionManager interface, and in order to carry out his or her job, the manager needs a group of voters which implement the AccessDecisionVoter interface.

The AccessDecisionManagers provided by Spring are:

  • A ffirmativeBased: At least one voter votes to grant access
  • C onsensusBased: A consensus of voters votes to grant access
  • U nanimousBased: All voters vote to abstain or grant access

If none of them is specifi ed, we employ AffirmativeBased with two voters, RoleVoter and AuthenticatedVoter. A voter can vote to grant, deny, or abstain. R oleVoter: This bases its vote on role. If the user has the required role by the required resource, it votes ACCESS_GRANTED. But if the resource doesn’t have a specifi ed role, it votes ACCESS_ABSTAIN. If the resource has a role the user doesn’t have, then it votes ACCESS_DENIED.

AuthenticatedVoter: This votes on the strength of the user’s authentication. A user can be authenticated with:

  • IS_AUTHENTICATED_FULLY
  • IS_AUTHENTICATED_REMEMBERED
  • IS_AUTHENTICATED_ANONYMOUSLY

[code lang=”java”]
AuthenticatedVoter votes ACCESS_GRANTED if the
authentication level is higher than the level requested by the
resource. The highest one is IS_AUTHENTICATED_FULLY.
In the following XML, we see the declaration of the access decision manager:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/security

http://www.springframework.org/schema/security/spring-security-

2.0.4.xsd
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
…
<bean id="accessDecisionManager">
<property name="decisionVoters">
<list>
<bean />
<bean
/>
</list>
</property>
</bean>
</beans>
[/code]

Once we have defi ned the AccessDecisionManager, we can use AOP to decide the roles that are necessary to call the several beans’ methods. We can employ three strategies:

  • Securing methods with security interceptors.
  • Securing methods with pointcuts.
  • Securing methods with annotations.

Securing methods with security interceptors

With security interceptors we can defi ne the roles necessary to execute methods on the bean.

[code lang=”java”]
Let’s have the interface:
public interface FooService {
public Integer getBalance(Integer idAccount);
public void setBalanceAccount(Integer id, Integer balance);
public boolean suspendAccount(Integer id);
}
FooService is implemented by FooServiceImpl, that is confi gured as follows :
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

http://www.springframework.org/schema/security

http://www.springframework.org/schema/security/spring-security-

2.0.4.xsd">
…
<bean id="accessDecisionManager">
<property name="decisionVoters">
<list>
<bean
/>
<bean
/>
</list>
</property>
</bean>
…
<bean>
<security:intercept-methods
access-decision-manager-ref="accessDecisionManager">
<security:protect method="org.springaop.chapter.five.
security.FooService.getBalance"
access="ROLE_USER" />
<security:protect
method="org.springaop.chapter.five.security.FooService.
setBalanceAccount"
access="ROLE_ACCOUNTING,ROLE_ADMIN" />
<security:protect method="org.springaop.chapter.five.
security.FooService.suspendAccount"
access="ROLE_ADMIN" />
</security:intercept-methods>
</bean>
…
</beans>
[/code]

We have defined some roles (separated by a comma) that can execute those method we want to be executed by a user that has a particular role. This choice permits us to define roles on methods directly on beans, but makes the confi guration files too long.

Securing methods with pointcuts

With this strategy, it’s possible to defi ne the roles required for the different pointcuts with AspectJ syntax that we defi ne with the tag global-method-security. We use the same rules on the same methods of the interface FooService.

[code lang=”java”]
<global-method-security
access-decision-manager-ref="accessDecisionManager">
<protect-pointcut
expression="execution(* org.springaop.chapter.five.security.
FooService.getBalance(..))"
access="ROLE_USER" />
<protect-pointcut
expression="execution(* org.springaop.chapter.five.security.
FooService.set*(..))"
access="ROLE_ACCOUNTING,ROLE_ADMIN" />
<protect-pointcut
expression="execution(* org.springaop.chapter.five.security.
FooService.suspendAccount(..))"
access="ROLE_ADMIN" />
</global-method-security>
[/code]

When using pointcuts, we don’t have to use interceptors if they can be in confl ict with the execution of methods that we have defi ned in the confi guration. This modality of confi guration is consistent with AspectJ syntax for the definition of pointcuts, making the modality of confi guration of aspects homogeneous. Compared to interceptors, the confi guration is less prolix and dispersive as it concentrates the methods that can be invoked with the different roles at one point.

Securing methods with annotations

We can use annotations to defi ne which roles can be executed by the methods of our classes. We will use the same rules on the same methods of the interface FooService.

[code lang=”java”]
package org.springaop.chapter.five.security;
import org.springframework.security.annotation.Secured;
public class FooServiceImplWithAnnotations implements FooService{
@Secured("ROLE_USER")
public Integer getBalance(Integer idAccount) {
Integer result = 0;
// do something
return result;
}
@Secured( { "ROLE_ACCOUNTING", "ROLE_ADMIN" })
public void setBalanceAccount(Integer id, Integer balance) {
// do something
}
@Secured("ROLE_ADMIN")
public boolean suspendAccount(Integer id) {
boolean result = false;
// do something
return result;
}
}
[/code]

With this strategy, we defi ne the roles within the class, needed for the execution of methods. With this choice we don’t have to confi gure any XML, but we lose the possibility of seeing the roles for the methods present defi ned in a single place.

also read:

  • Spring Framework Interview Questions
  • Introduction to Spring Framework
  • Spring and Hibernate Integration
  • Spring Framework Books (recommended)

Summary

In this chapter we’ve seen how to implement crosscutting functionalities, such as concurrency control, the employment of a cache, and security management. Without AOP those functionalities would be scattered across the application, with the same code duplicated in different modules. With AOP we can have cleaner code, much more concise and easier to maintain and debug. We’ve seen how it is possible to implement these functionalities without having tangled or scattered code, implementing functionalities with aspects and advices.

Other important functionalities are transactions management, application logging, exception management, layout, and others. They will be illustrated in the next twox chapters in a complete and working application.

Filed Under: Spring Framework Tagged With: Book Review, Spring AOP

Follow Us

  • Facebook
  • Pinterest

As a participant in the Amazon Services LLC Associates Program, this site may earn from qualifying purchases. We may also earn commissions on purchases from other retail websites.

JavaBeat

FEATURED TUTORIALS

Answered: Using Java to Convert Int to String

What is new in Java 6.0 Collections API?

The Java 6.0 Compiler API

Copyright © by JavaBeat · All rights reserved