<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6851845813602526520</id><updated>2012-02-02T01:09:45.919-08:00</updated><category term='aop'/><category term='personal'/><category term='java'/><category term='spring'/><title type='text'>Not So Much...</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ryanbreidenbach.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6851845813602526520/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ryanbreidenbach.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Ryan Breidenbach</name><uri>http://www.blogger.com/profile/08321479442409262496</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>4</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6851845813602526520.post-1313580197738920155</id><published>2006-10-28T18:00:00.000-07:00</published><updated>2006-10-30T06:23:23.546-08:00</updated><title type='text'>NFJS Dallas Retrospective</title><content type='html'>I just finished the &lt;a href="http://www.nofluffjuststuff.com/"&gt;No Fluff Just Stuff&lt;/a&gt; Dallas Symposium. First, let me say that I am exhausted. Two and half days of in-depth sessions wears me out. Second, this was my third (or fourth, I can't remember) &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;NFJS&lt;/span&gt; and this one was business as usual:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Excellent (for the most part) sessions focused on a core set of topics - agile, Java, Ruby, Spring, testing, etc.&lt;/li&gt;&lt;li&gt;Laid back atmosphere. It doesn't feel like a conference, but more like one big &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;BOF&lt;/span&gt;. And you can tell that most of the speakers have a good relationship with one another, probably from spending so much time "touring" together. Overall, it's a really friendly atmosphere.&lt;/li&gt;&lt;li&gt;Well organized and well run.&lt;/li&gt;&lt;/ul&gt;Here are my general take aways regarding specific technologies and the industry in general:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;AOP&lt;/span&gt; is here to stay. Duh&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;!&lt;/span&gt; I know this sounds obvious, but most Java developers &lt;span style="font-style: italic;"&gt;aren't&lt;/span&gt; using aspects. Even so, some speakers said it is mainstream. I don't think it is mainstream - to me people still don't get it or get it but fear it. But it &lt;span style="font-style: italic;"&gt;is&lt;/span&gt; clearly well rooted and will keep seeping into more and more companies. This is great news.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;We, as an industry, are still &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;learning&lt;/span&gt; web services&lt;/span&gt;. I attended a couple of web services sessions, and the questions from the audience indicated that there is still a lot of confusion in this area. Even the speakers at these sessions provided more "guidance" in this area rather than concrete solutions. Unfortunately, I don't think much in this area is black and white with many lessons still to be learned. &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;C'est&lt;/span&gt; la vie.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Groovy is making a comeback&lt;/span&gt;. A few years ago, Groovy exploded onto the Java landscape. For a while, you couldn't read a Java website or blog without seeing Groovy being discussed. Then...silence. I don't know exactly what caused this or where Groovy went. To me, it seemed like Groovy wasted a lot of initial momentum. But Groovy appears to be popping up again in several places, or it has always been there and is popping up on my radar again :-) &lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;People are interested in Agile, but people aren't practicing Agile&lt;/span&gt;. This is a &lt;span style="font-style: italic;"&gt;huge&lt;/span&gt; generalization, but the agile sessions are packed yet many people haven't adopted some basic agile practices - unit tests, CI, simple-enough-to-work design. I'm not sure why this is. Perhaps some of it is the typical "management" distrust. But I think part of it is A&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;gile's&lt;/span&gt; dirty little secret - Agile is &lt;span style="font-style: italic;"&gt;hard&lt;/span&gt;. Not hard as in confusing or complicated. Rather, agile practices require a lot of discipline and a lot of developers/teams just aren't that disciplined. I could be wrong.&lt;/li&gt;&lt;/ul&gt;Lastly, at the risk of sounding like a geek groupie, but there are a couple of speakers I feel are a can't miss if you get a chance to see them. First, &lt;a href="http://www.vanderburg.org/"&gt;Glenn &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Vanderburg&lt;/span&gt;&lt;/a&gt; is just &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;freakin&lt;/span&gt;' smart. His peak deep inside the rabbit hole that is the inner workings of JavaScript made my brain hurt (which is a good thing I think). His talk on Java Performance Myths was also fascinating. If you have been in Java for some time, none of this information (e.g. GC really isn't slow any more) is new, but it is still worth attending. Second, &lt;a href="http://blogs.tedneward.com/"&gt;Ted &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;Neward&lt;/span&gt;&lt;/a&gt; is worth seeing no matter the subject matter.  The depth and breadth of his technical knowledge is truly impressive - he always seem to have an answer (real, not faked) to any question, no matter how complex or obscure. Oh, and try to start an argument with him for fun.&lt;br /&gt;&lt;br /&gt;Congratulations Jay on another great conference.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6851845813602526520-1313580197738920155?l=ryanbreidenbach.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryanbreidenbach.blogspot.com/feeds/1313580197738920155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6851845813602526520&amp;postID=1313580197738920155' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6851845813602526520/posts/default/1313580197738920155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6851845813602526520/posts/default/1313580197738920155'/><link rel='alternate' type='text/html' href='http://ryanbreidenbach.blogspot.com/2006/10/nfjs-dallas-wrap-up-part.html' title='NFJS Dallas Retrospective'/><author><name>Ryan Breidenbach</name><uri>http://www.blogger.com/profile/08321479442409262496</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6851845813602526520.post-1621428100085318937</id><published>2006-09-26T21:23:00.000-07:00</published><updated>2006-09-26T21:48:45.511-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='aop'/><title type='text'>Spring, DDD and AspectJ - An Example</title><content type='html'>In my &lt;a href="http://ryanbreidenbach.blogspot.com/2006/09/aop-meets-ddd.html"&gt;last post&lt;/a&gt;, I discussed the possibilty of using AspectJ with Spring to inject domain objects with service objects to create a richer domain model. This follow up is to explore some example code based on a Customer -&gt; Account example given by &lt;a href="http://ramnivas.com/"&gt;Ramnivas&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;In this example, we are trying to get the net worth of a &lt;span style="font-family:courier new;"&gt;Customer&lt;/span&gt; object. A &lt;span style="font-family:courier new;"&gt;Customer&lt;/span&gt; object has a relationship with an &lt;span style="font-family:courier new;"&gt;Account&lt;/span&gt; object, but it only has a reference to the &lt;span style="font-family:courier new;"&gt;Account&lt;/span&gt; object's id:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public class Customer {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private Long accountId;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public Long getAccountId() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return accountId; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public void setAccountId(Long accountId) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.accountId = accountId;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The value of the account is used to determine the customer's net worth. Suppose we have a &lt;span style="font-family:courier new;"&gt;CustomerService&lt;/span&gt; interface that exposes this operation via its &lt;span style="font-family:courier new;"&gt;getNetWorth(Customer)&lt;/span&gt; method. One implementation of this method would be to place most of the logic in the service layer like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public Double getNetWorth(Customer customer) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Long accountId = customer.getAccountId();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Account account = accountRepository.getAccountById(accountId);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return account.getValue();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is a classic example of an &lt;a href="http://www.martinfowler.com/bliki/AnemicDomainModel.html"&gt;anemic domain model&lt;/a&gt;. All of the business logic is in the service layer and the domain objects are simply data containers. But in OO, an object = data + behavior, right? So how do we push this behavior back to the domain layer?&lt;br /&gt;&lt;br /&gt;This biggest question in this particular scenario is how can a &lt;span style="font-family:courier new;"&gt;Customer&lt;/span&gt; object obtain a reference to its &lt;span style="font-family:courier new;"&gt;Account&lt;/span&gt; object? Well, there are several ways:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;It could be given a reference to the &lt;span style="font-family:courier new;"&gt;Account&lt;/span&gt; object by the &lt;span style="font-family:courier new;"&gt;CustomerService&lt;/span&gt; object. But that really isn't much different than the example above. The &lt;span style="font-family:courier new;"&gt;CustomerService&lt;/span&gt; class is still two involved in the business logic.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;This &lt;span style="font-family:courier new;"&gt;Customer&lt;/span&gt; object could actively obtain a reference to the &lt;span style="font-family:courier new;"&gt;AccountRepository&lt;/span&gt; via a &lt;a href="http://www.martinfowler.com/articles/injection.html#UsingAServiceLocator"&gt;service locator&lt;/a&gt;. But this introduces a dependency not only on the &lt;span style="font-family:courier new;"&gt;AccountRepository&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;&lt;/span&gt;, but the service locator as well - not a very transparent solution.&lt;/li&gt;&lt;li&gt;The &lt;span style="font-family:courier new;"&gt;AccountRepository&lt;/span&gt; object could be supplied to the &lt;span style="font-family:courier new;"&gt;Customer&lt;/span&gt; object using &lt;a href="http://www.martinfowler.com/articles/injection.html#FormsOfDependencyInjection"&gt;dependency injection&lt;/a&gt;. This makes sense - after all, we are doing this with our Spring beans already in our service/data access layers.&lt;/li&gt;&lt;/ol&gt;Implementing option #3 is where AspectJ comes in. While Spring manages the lifecycle of service and data access beans, it does not manage the lifecycle of domain objects. These can be instantiated via &lt;span style="font-family:courier new;"&gt;new&lt;/span&gt; or by another framework, such as Hibernate. However, AspectJ &lt;span style="font-style: italic;"&gt;can&lt;/span&gt; weave advice into the domain object's classes that is executed after their constructor completes. There are several pieces to this puzzle. First let's take a look at the "enriched" &lt;span style="font-family:courier new;"&gt;Smart&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;Customer&lt;/span&gt; class:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;@Configurable("smartCustomer")&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public class SmartCustomer extends Customer {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private AccountRepository accountRepository;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public AccountRepository getAccountRepository() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return accountRepository;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public void setAccountRepository(AccountRepository accountRepository) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.accountRepository = accountRepository;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public Double getNetWorth() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Account account = accountRepository.getAccountById(getAccountId());&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return account.getValue();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now a &lt;span style="font-family:courier new;"&gt;Customer&lt;/span&gt; object can obtain a reference to its associated &lt;span style="font-family:courier new;"&gt;Account&lt;/span&gt; object via the &lt;span style="font-family:courier new;"&gt;AccountRepository&lt;/span&gt;.  But how does it obtain a reference to the &lt;span style="font-family:courier new;"&gt;AccountRepository&lt;/span&gt;? Notice the &lt;span style="font-family:courier new;"&gt;@Configurable&lt;/span&gt; annotation. This is basically a marker that identifies this class as needing to be configured by Spring whenever a new instance is created.  This "magic" is possible because AspectJ weaves in advice into the &lt;span style="font-family:courier new;"&gt;SmartCustomer&lt;/span&gt;'s constructor. I have not delved into the details, but I suppose this advice is aware of the Spring application context.&lt;br /&gt;&lt;br /&gt;Spring knows how to configure each instance of this class from a prototype bean configured in the application context:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;bean id="smartCustomer" abstract="true" class="org.springdallasug.aspectj.domain.SmartCustomer" scope="prototype" &amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="accountRepository" ref="accountRepository" /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now every instance of the &lt;span style="font-family:courier new;"&gt;SmartCustomer&lt;/span&gt; class will be wired with an &lt;span style="font-family:courier new;"&gt;AccountRepository &lt;/span&gt;object. In order to make this happen, AspectJ must weave this advice into the &lt;span style="font-family: courier new;"&gt;SmartCustomer&lt;/span&gt; class. For my demo, I chose to use load time weaving. This is done by starting the JVM with the following option:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;-javaagent:PATH_TO_JAR/aspectjweaver-1.5.0.jar&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This enables AspectJ to weave advice into classes as they are being loaded into the JVM. For anybody interested, I have packaged up this simple &lt;a href="http://www.geocities.com/ryan_breidenbach/aspectj-demo.zip"&gt;demo&lt;/a&gt;. The entire mechanics behind this can be found in the &lt;a href="http://static.springframework.org/spring/docs/2.0.x/reference/aop.html#aop-using-aspectj"&gt;Spring documentation&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So, it &lt;span style="font-style: italic;"&gt;is&lt;/span&gt; pretty cool that Spring + AspectJ makes it straightforward to apply dependency injection to domain objects. But the question remains, is this the right thing to do? Taking the example above, allowing a &lt;span style="font-family:courier new;"&gt;Customer&lt;/span&gt; object to completely contain the logic of calculating its own net worth means it needs access to its &lt;span style="font-family:courier new;"&gt;Account&lt;/span&gt; object. But this, in turn, means giving it access to the &lt;span style="font-family:courier new;"&gt;AccountRepository&lt;/span&gt;. This is, for me at least, an unusual design decision. While this does create a "richer" domain model, at adds more (potentially complex) dependencies into the domain model.&lt;br /&gt;&lt;br /&gt;I don't think the answer is cut and dry. Instead, it probably needs to be fleshed out in a "real world" application. I just might have to try that.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Edit:&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.springinaction.com"&gt;Craig Walls&lt;/a&gt; pointed out a couple of improvements to this example. First, I added the name of the prototype bean to the annotation to be more explicit (I also added the "id" attribute to the SmartCustomer bean in the Spring configuration file). Second, I made the prototype bean abstract, which prevents the Spring container from ever instantiating an instance - it is now strictly a prototype. Not a big thing, but it is an improvement. Thanks Craig.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6851845813602526520-1621428100085318937?l=ryanbreidenbach.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryanbreidenbach.blogspot.com/feeds/1621428100085318937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6851845813602526520&amp;postID=1621428100085318937' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6851845813602526520/posts/default/1621428100085318937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6851845813602526520/posts/default/1621428100085318937'/><link rel='alternate' type='text/html' href='http://ryanbreidenbach.blogspot.com/2006/09/spring-ddd-and-aspectj-example.html' title='Spring, DDD and AspectJ - An Example'/><author><name>Ryan Breidenbach</name><uri>http://www.blogger.com/profile/08321479442409262496</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6851845813602526520.post-7729835706432469017</id><published>2006-09-21T21:16:00.000-07:00</published><updated>2006-09-21T21:52:30.515-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='aop'/><title type='text'>AOP meets DDD</title><content type='html'>Yesterday I attended the &lt;a href="http://springdallasug.org/"&gt;Dallas Spring Users Group&lt;/a&gt;.  The September speaker was &lt;a href="http://ramnivas.com/blog/"&gt;Ramnivas Laddad&lt;/a&gt;. The topic of the presentation was Spring AOP and AspectJ. I was interested in hearing about how Spring leverages the AspectJ pointcut syntax in Spring 2.0. I am quite familiar with Spring 1.2's type of AOP. I have experimented with the AspectJ pointcut language, but I wanted to get some guidance on best practices.&lt;br /&gt;&lt;br /&gt;Well, this topic was covered quite well. But at the end of the presentation he focused on how to leverage the full power of AspectJ - advising classes vs. advising objects via proxies. One of the last slides he presented was how to use AspectJ to inject dependencies into domain objects. This point was sort of mentioned in passing, but it raises a very interesting debate. Is using aspects to inject domain objects with dependencies (possibly service-type objects) the right way to create a richer domain model?&lt;br /&gt;&lt;br /&gt;After the presentation we discussed a concrete example. Suppose you have a &lt;span style="font-family:courier new;"&gt;Customer&lt;/span&gt; object. In the domain, the Customer has an Account, but in the object model, a &lt;span style="font-family:courier new;"&gt;Customer&lt;/span&gt; object only has a reference to its &lt;span style="font-family:courier new;"&gt;Account&lt;/span&gt;'s id (following the notion of an aggregate root in domain driven design). Now suppose the service layer supports the method &lt;span style="font-family:courier new;"&gt;getNetWorth(Customer)&lt;/span&gt;.  Without a rich domain object, the service would be responsible for retrieving the &lt;span style="font-family:courier new;"&gt;Account&lt;/span&gt; object on behalf of the &lt;span style="font-family:courier new;"&gt;Customer&lt;/span&gt; object and returning the value of the Account. Something like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Account account = accountRepository.getAccount(customer.getAccountId();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;return account.getValue();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Bu&lt;/span&gt;&lt;/span&gt;t suppose we want this logic to exist in the &lt;span style="font-family:courier new;"&gt;Customer&lt;/span&gt; object, as it should with a rich domain model. How would the &lt;span style="font-family:courier new;"&gt;Customer&lt;/span&gt; object obtain a reference to its &lt;span style="font-family:courier new;"&gt;Account&lt;/span&gt; object? The answer is it needs access the &lt;span style="font-family:courier new;"&gt;AccountRespository&lt;/span&gt;, And AspectJ + Spring can help achieve this. Basically, an AspectJ aspect (woven into the &lt;span style="font-family:courier new;"&gt;Customer&lt;/span&gt; class) would be invoked that would inject the &lt;span style="font-family:courier new;"&gt;AccountRepository&lt;/span&gt; bean from the Spring context whenever a &lt;span style="font-family:courier new;"&gt;Customer&lt;/span&gt; object in instantiated.&lt;br /&gt;&lt;br /&gt;Now, for those who are knee-deep in full blown aspects, this is probably not a novel idea. But for those of us who have simply lived in the proxy-based aspect world., this opens up a whole new realm of possiblities. The implication of having a rich domain model (as opposed to much of the business logic remaining in the service layer) is quite intriguing. However, it raised many questions:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Is going whole-hog aspects right for my application? Going from proxy-based AOP to full-blown aspects is not a small step.&lt;/li&gt;&lt;li&gt;Is giving the domain layer access to other services/data access objects a good design?&lt;/li&gt;&lt;li&gt;What sort of recursive dependencies will be introduced when the domain becomes aware of these layers?&lt;/li&gt;&lt;/ul&gt;I am looking forward to delving into these questions. The possibilty of having "real" domain layer is way too interesting to ignore, I am not ready to drink the Kool-Aid, but I am ready for a taste.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6851845813602526520-7729835706432469017?l=ryanbreidenbach.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryanbreidenbach.blogspot.com/feeds/7729835706432469017/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6851845813602526520&amp;postID=7729835706432469017' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6851845813602526520/posts/default/7729835706432469017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6851845813602526520/posts/default/7729835706432469017'/><link rel='alternate' type='text/html' href='http://ryanbreidenbach.blogspot.com/2006/09/aop-meets-ddd.html' title='AOP meets DDD'/><author><name>Ryan Breidenbach</name><uri>http://www.blogger.com/profile/08321479442409262496</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6851845813602526520.post-1510446947995121436</id><published>2006-08-26T19:53:00.000-07:00</published><updated>2006-08-26T20:05:58.725-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>Hard Drive Failure</title><content type='html'>So a few weeks ago I broke down and bought a new &lt;a href="http://www.blaptops.com/hp/hp-pavilion-dv5000t-review/"&gt;laptop&lt;/a&gt;. With 2GB of RAM and 120GB hard drive, this looked like a great deal at $999. Up until today, everything was great and I was loving my new toy. But tonight while ripping a CD it froze. "No big deal," I thought and I just powered the PC down. Well, it never came back up. Instead, the hard drive is dead and I have to send it in for a new one. I just hope this isn't a hint of things to come.&lt;br /&gt;&lt;br /&gt;Let this be a lesson to all you kids out there - BACK UP YOUR DATA.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6851845813602526520-1510446947995121436?l=ryanbreidenbach.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryanbreidenbach.blogspot.com/feeds/1510446947995121436/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6851845813602526520&amp;postID=1510446947995121436' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6851845813602526520/posts/default/1510446947995121436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6851845813602526520/posts/default/1510446947995121436'/><link rel='alternate' type='text/html' href='http://ryanbreidenbach.blogspot.com/2006/08/hard-drive-failure.html' title='Hard Drive Failure'/><author><name>Ryan Breidenbach</name><uri>http://www.blogger.com/profile/08321479442409262496</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
