Autowire取决于子类

Jee*_*aim 8 inheritance spring autowired

我有一个抽象类AbstractService,它引用了AbstractDAO

class AbstractService{  
   protected AbstractDAO abstractDAO;  
}
Run Code Online (Sandbox Code Playgroud)

AbstractService将实际服务等级等来扩展ServiceClassA,ServiceClassB等等,并且AbstractDAO将被扩展DaoClassA,DaoClassB等等.

取决于其类的扩展AbstractService,abstractDAO应该是一个实例DaoClassA,DaoClassB

我可以通过在扩展类中使用abstractDAO setter来实现这一点

class ServiceClassA{    
    @Autowired  
    @Qualifier("daoClassA")  
    public void setAbstractDAO(AbstractDAO abstractDAO) {  
        super.abstractDAO = abstractDAO;  
    }   
}  
Run Code Online (Sandbox Code Playgroud)

是否有任何方法可以setAbstractDAOAbstractService类本身中使用setter 并abstractDAO根据子类获得Autowired可能是SPEL + Qualifier等

我们不想为此使用任何XML配置

JB *_*zet 8

我不会这样做.实际上,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
}
Run Code Online (Sandbox Code Playgroud)


Gon*_*ndy 5

我和你一样正在解决类似的问题。我找到了另一种方法,您不必创建 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);
    }

}
Run Code Online (Sandbox Code Playgroud)

@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");
    }    
}
Run Code Online (Sandbox Code Playgroud)

最后,现在您可以使用具体的 Service 类和具体的 DAO 类调用您的通用服务:(当然您可以在某处自动装配它们)

((AbstractService) context.getBean("serviceClassA")).service();
((AbstractService) context.getBean("serviceClassB")).service();
Run Code Online (Sandbox Code Playgroud)

将打印:

I am DaoClassA
I am DaoClassB
Run Code Online (Sandbox Code Playgroud)