I'm building a REST service with Spring / Hibernate / Restlet / Jetty and I'm struggling with what I thought to be a simple task:
I need to inject DAO implementation (i.e. UserDao) to a ServerResource (in this case UserServerResource).
I'm using SpringRouter bean to establish routing to this resource in Spring XML configuration:
<bean name="restlet-user-server-resource"
class="project.server.rest.UserServerResource"
scope="prototype" />
<bean name="restlet-api-server-application"
class="org.restlet.Application">
<property name="inboundRoot">
<bean class="org.restlet.ext.spring.SpringRouter">
<constructor-arg ref="restlet-api-server-application" />
<property name="attachments">
<map>
<entry key="/user/{userId}"
value-ref="restlet-user-server-resource" />
</map>
</property>
</bean>
</property>
</bean>
And I've tried to inject the DAO both as @Autowired and as bean property (in "restlet-user-server-resource" bean p:userDao-ref="user-dao").
UserDao is specified as:
<bean name="user-dao,userDao"
parent="dao-tx-template">
<property name="target">
<bean class="project.server.data.dao.UserDao"
p:sessionFactory-ref="session-factory" />
</property>
</bean>
Should be noted, that getBean('user-dao') works as expected and returns fully prepared instance of UserDao.
I've tried following:
Also, in both (1) and (3), error is issued by Restlet: Unknown object found in the mappings. Only instances of Restlet and subclasses of org.restlet.resource.Resource and ServerResource are allowed.
Adding the current UserServerResource implementation (which is nothing, just a mock for infrastructure setup):
package project.server.rest;
import org.restlet.resource.ResourceException;
import org.restlet.resource.ServerResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import project.server.data.dao.UserDao;
import project.server.data.entities.User;
import project.server.rest.interfaces.UserResource;
@Configurable
public class UserServerResource
extends ServerResource
implements UserResource
{
private int userId;
@Autowired
private UserDao userDao;
@Override
public void doInit() throws ResourceException
{
String userIdString = (String)this.getRequestAttributes().get("userId");
this.userId = Integer.parseInt(userIdString);
}
@Override
public User represent()
{
System.out.println(this.userDao);
User user = new User();
user.setId(this.userId);
user.setUserName("Something");
user.setEmailAddress("some@address.com");
return (user);
}
public void setUserDao(UserDao dao)
{
this.userDao = dao;
}
public UserDao getUserDao()
{
return (this.userDao);
}
}
I hope I've provided as much info as possible. Thank you for any advice!
Ok, I've made some desperate Google Searches and found a Restlet's Spring extension manual page once again, but now, not missing important point, which at the end solved my struggle. Here is the solution:
<bean name="restlet-user-server-resource"
class="project.server.rest.UserServerResource"
scope="prototype"
p:userDao-ref="user-dao" />
<bean name="restlet-api-server-application"
class="org.restlet.Application">
<property name="inboundRoot">
<bean class="org.restlet.ext.spring.SpringRouter">
<constructor-arg ref="restlet-api-server-application" />
<property name="attachments">
<map>
<entry key="/user/{userId}">
<bean class="org.restlet.ext.spring.SpringFinder">
<lookup-method name="create" bean="restlet-user-server-resource" />
</bean>
</entry>
</map>
</property>
</bean>
</property>
</bean>
Important bit is the SpringFinder bean with create method used to lookup and instantiate the Spring bean instead of direct reference.