Referencing beans without an id
Question
I'm trying to reference a JPA repository using Spring expression language in Activiti. However since Spring is creating the repository beans using <jpa:repositories/>
, they don't have an id associated with them. Is there a way to use SpEL to reference a bean of a certain type instead of by id? I tried using what I thought would be the generated name (locationRepository) for the LocationRepository
, but no success.
Solution
I'm assuming LocationRepository
is an interface, and that the backing implementation is being generated for you. When Spring creates a bean and no id is explicitly specified, it usually uses the class name of the implementation class to determine the bean id. So in this case your LocationRepository
's id is probably whatever the name of the generated class is.
But since we don't know what it is, we can create a Spring FactoryBean
which just gets LocationRepository
from the app context via autowiring and puts it back into the app context under a new name.
public class LocationRepositoryFactoryBean extends AbstractFactoryBean<LocationRepository> {
@Autowired
private LocationRepository bean;
public Class<?> getObjectType() { return LocationRepository.class; }
public Object createInstance() throws Exception { return bean; }
}
In your app context xml:
<bean name="locationRepository" class="your.package.LocationRepositoryFactoryBean"/>
You should then be able to refer to your LocationRepository
object with the bean id locationRepository.
OTHER TIPS
Not sure how to do this in SPEL but you can use @Qualifier
to decide which bean should be injected.
If you want you can create your own custom @Qualifier annotation and access bean based on it.
Like
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier // Just add @Qualifier and you are done
public @interface MyRepository{
}
Now use @MyRepository
annotation in repository bean and other place where you want to inject it.
@Repository
@MyRepository
class JPARepository implements AbstractRepository
{
//....
}
Injecting it
@Service
class fooService
{
@Autowire
@MyRepositiry
AbstractRepository repository;
}