I'm playing with the idea of using Spring @Configurable
and @Autowire
to inject DAOs into domain objects so that they do not need direct knowledge of the persistence layer.
I'm trying to follow http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-atconfigurable, but my code seems to have no effect.
Basically, I have:
@Configurable
public class Artist {
@Autowired
private ArtistDAO artistDao;
public void setArtistDao(ArtistDAO artistDao) {
this.artistDao = artistDao;
}
public void save() {
artistDao.save(this);
}
}
And:
public interface ArtistDAO {
public void save(Artist artist);
}
and
@Component
public class ArtistDAOImpl implements ArtistDAO {
@Override
public void save(Artist artist) {
System.out.println("saving");
}
}
In application-context.xml, I have:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springsource.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />
<bean class="org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect" factory-method="aspectOf"/>
</beans>
Class path scanning and initialisation is performed by the spring module for Play! framework, although other autowired beans work, so I'm pretty sure this is not the root cause. I'm using Spring 3.0.5.
In other code (inside a method in bean that's injected into my controller using Spring, in fact), I'm doing this:
Artist artist = new Artist();
artist.save();
This gives me a NullPointerException trying to access the artistDao in Artist.save().
Any idea what I'm doing wrong?
Martin
First, enable Spring debug logging. I use Log4j to do it. I've created a logger like so (with Log4j xml configuration so I can use RollingFileAppender):
This will allow you to see what Spring is doing and when.
Second, you have ArtistDAO autowired but I don't see where you have a bean named ArtistDAO. Your DAO component bean will be named "artistDaoImpl" by default. Try changing
@Component
to@Component("artistDao")
and applying@Autowired
to the setter instead:Also, please verify that your version of AspectJ is current. I wasted a few hours trying to make this work, and the cause was an old version of Aspectjweaver.jar. I updated to 1.7.2 and everything worked like a charm.
I had the same problem and never managed to get the code working with @Configurable and @Autowired. I finally decided to write an aspect myself which would handle the @Configurable and @Autowired annotations. Here is the code:
Next in your spring context define the aspect so that the springcontext will be injected into the aspect
I had a similar issue that I resolved today. The important thing is that you need to enable load-time weaving and make sure the appropriate aspectj classes are loaded. In your pom.xml you need to add the aspectjweaver artifact:
You can change the version if you need to. Then, I would go the xsd route in you application-context.xml instead of the DTD route:
Perhaps using the @Repository annotation for the DAO will do it.
try : @Configurable(autowire=Autowire.BY_TYPE). Autowired defaults to off :<