我有一个抽象类AbstractService
,它引用了AbstractDAO
class AbstractService{
protected AbstractDAO abstractDAO;
}
AbstractService
将通过ServiceClassA
,ServiceClassB
等实际服务类进行扩展,
AbstractDAO
将DaoClassA
,DaoClassB
等扩展{/ 1}。
根据扩展的AbstractService
类,abstractDAO
应该是DaoClassA
,DaoClassB
等的实例
我可以通过在扩展类中使用abstractDAO setter来实现这一点,如
class ServiceClassA{
@Autowired
@Qualifier("daoClassA")
public void setAbstractDAO(AbstractDAO abstractDAO) {
super.abstractDAO = abstractDAO;
}
}
有没有办法让setAbstractDAO
类中的setter AbstractService
本身
并且abstractDAO
获取自动装配,具体取决于子类,可能是SPEL +限定符等
我们不想为此
使用任何XML配置答案 0 :(得分:7)
我不会这样做。实际上,ServiceClassA很可能依赖于DaoClassA的某些特定方法。在这种情况下,每次要调用这种特定方法时,都必须将受保护的AbstractDAO强制转换为DaoClassA。
我会使它变得通用,并反转依赖注入的方式:
public class AbstractService<T extends AbstractDAO> {
protected T dao;
protected AbstractService(T dao) {
this.dao = dao;
}
// methods common to all the services
}
public class ServiceClassA extends AbstractService<DaoClassA> {
@Autowired
public ServiceClassA(DaoClassA dao) {
super(dao);
}
// methods specific to ServiceClassA
}
答案 1 :(得分:2)
我像你一样解决了类似的问题。我找到了另一种方法,你不必创建setter方法。而不是使用常规构造函数,而是使用Spring自动装配。这是完整的代码:
服务类:
public abstract class AbstractService {
protected final AbstractDAO dao;
// Constructor forces you to inject dao in subclass
public AbstractService(final AbstractDAO dao) {
this.dao = dao;
}
public final void service() {
// you can do something generic here with 'dao'
// no matter which subclass is injected
this.dao.doSomething();
}
}
@Component
public class ServiceClassA extends AbstractService {
@Autowired
public ServiceClassA(@Qualifier("daoClassA") final AbstractDAO dao) {
super(dao);
}
}
@Component
public class ServiceClassB extends AbstractService {
@Autowired
public ServiceClassB(@Qualifier("daoClassB") final AbstractDAO dao) {
super(dao);
}
}
注意子类构造函数中的@Qualifier("daoClassA")
字段类:
public interface AbstractDAO {
public void doSomething();
}
@Component
public class DaoClassA implements AbstractDAO {
@Override
public void doSomething() {
System.out.println("I am DaoClassA");
}
}
@Component
public class DaoClassB implements AbstractDAO {
@Override
public void doSomething() {
System.out.println("I am DaoClassB");
}
}
最后,现在您可以使用具体的Service类和具体的DAO类来调用您的通用服务:(当然您可以在某处自动装配它们)
((AbstractService) context.getBean("serviceClassA")).service();
((AbstractService) context.getBean("serviceClassB")).service();
将打印:
I am DaoClassA
I am DaoClassB
答案 2 :(得分:0)
不,没有。您无法访问当前从SPEL填充AutowiredAnnotationBeanPostProcessor
的类或bean名称。
您可以覆盖AbstractBeanFactory.evaluateBeanDefinitionString
并在beanDefinition
中添加BeanExpressionContext
作为变量。然后你可以从服务中派生出Dao。在@Value注释中使用SPEL。