Showing posts with label aspectj. Show all posts
Showing posts with label aspectj. Show all posts

Friday, 8 February 2008

@Configurable example with Spring 2.5

Hey,
My first blog! I feel somewhat late on the blogging scene...but better late than never!

I recently did a simple (maybe too simple..i hope to add more features) example of using Spring 2.5 @Configurable. The example shows how to configure your domain objects (normally outside the control of the container,for example objects returned by Hibernate) so that dependencies can be injected by Spring.

Now I know there are a lot of opinions on why you would do this (Personally I like the idea of having DomainServices which aren't related to application services or infrastructure services). We can have this debate later but for those of you who are interested in doing this here are the following code samples.


DomainObject.java [package com.amin.spring.app.domain]

@Configurable(dependencyCheck=true)
public class DomainObject {
private String name;
private DomainService domainService;
@Autowired
public void setDomainService(DomainService domainService) {
this.domainService = domainService;
}

public DomainService getDomainService() {
return domainService;
}
public void setName(String name) {
boolean isValidName = domainService.isValidUserName(name);
if (!isValidName) {
throw new UsernameValidationException("username already used. please try alternative");
}
this.name = name;
}

public String getName() {
return this.name;
}
}


DomainService.java [package com.amin.spring.app.service]

public interface DomainService {
public boolean isValidUserName(String name);
}

DomainServiceImpl.java[package com.amin.spring.app.service] [the implementation class is simple! But it's to give you an idea]

@Service
public class DomainServiceImpl implements DomainService {
public boolean isValidUserName(String name) {
boolean isValidUserName = StringUtils.hasText(name); return isValidUserName;
}
}

conf/spring/bean.xml [snippet excluding xml declaration..be sure to use 2.5]

<context:annotation-config />
<context:spring-configured />
<context:load-time-weaver />
<context:component-scan base-package="com.amin.spring.app" />

Amazing...that's it!


DomainObjectTest.java [src/test/java - com.amin.spring.app.domain]

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/conf/spring/bean.xml"})
public class DomainObjectTest {

@Test
public void testServiceInjectionToDomainObject() throws Exception {
DomainObject domainObject = new DomainObject();
assertNotNull("Domain Service was not set", domainObject.getDomainService());
}

@Test
@ExpectedException(value=java.lang.RuntimeException.class)
public void testServiceInjectionToDomainObjectWithValidationException() throws Exception {
DomainObject domainObject = new DomainObject();
domainObject.setName(null);
assertNotNull("Validation Service was not set", domainObject.getDomainService());

}
}



Right...for this example I am using Load Time Weaving (you can do with build time weaving with Maven or Ant) which will enable AspectJ to weave classes that are marked with @Configurable, allowing Spring to inject any dependencies into domain object before it is returned to the calling code. In order to do this you will need to configure the run configuration of the testcase (i do this via eclipse). This can be done by adding the following to the JVM argument:
-javaagent:/spring-agent.jar

And then you're ready to go....

Feel free to comment on the blog and/or on the example code.