【发布时间】:2015-03-29 14:45:15
【问题描述】:
我有一个基本接口和两个实现
public interface AnimalService
{
public void eat();
}
@Service("animalService")
@Transactional
public class AnimalServiceImpl implements AnimalService
{
@Override
public void eat()
{
System.out.println("i'm eating");
}
}
@Service("birdService")
@Transactional
public class BirdServiceImpl extends AnimalServiceImpl
{
public void fly()
{
System.out.println("i'm flying");
}
}
在我的 main 方法中尝试以这种方式调用这两个服务实现:
public class test
{
@Autowired
private AnimalService animalService;
@Autowired
@Qualifier("birdService")
private AnimalService birdService;
public static void main(String[] args)
{
animalService.eat();
birdService.eat();
birdService.fly();
}
}
这会产生编译错误,因为birdService 找不到方法fly()。然后我想可能是因为我自动装配 AnimalService 而不是 BirdServiceImpl,所以我改变了我的自动装配代码:
@Autowired
@Qualifier("birdService")
private AnimalService birdService;
改为:
@Autowired
private BirdServiceImpl birdService;
但这会给我一个运行时错误,即“找不到 bean BirdServiceImpl”。 我有很多文档,有人说使用@Resource。但这对我不起作用。有人说在 Spring Context 中注册 bean,而我所有的 bean 注册都是通过注解完成的。我不想碰 Spring Context。
现在我的解决方案是添加一个新界面
public interface BirdService extends AnimalService
{
public void fly();
}
并让我的 BirdServiceImpl 来实现这个接口
public class BirdServiceImpl extends AnimalServiceImpl extends BirdService
{
public void fly()
{
System.out.println("i'm flying");
}
}
我的主班变成了这样:
public class test
{
@Autowired
private AnimalService animalService;
@Autowired
private BirdService birdService;
public static void main(String[] args)
{
animalService.eat();
birdService.eat();
birdService.fly();
}
}
现在好了。但对我来说,这并不完美。如果我使用纯 java,我可以只编写单个接口和多个实现。在主要方法中,我可以选择要使用的实现。为什么在春天,我必须为每个新实现构建一个新接口才能让我的程序运行。
我想知道我的场景有没有更好的方法?
【问题讨论】:
-
您的代码原样也不适用于纯 java。
AnimalService没有fly方法,无论您使用什么 Spring 或普通 java(哎呀 spring 是 java),它都找不到该方法。BirdServiceImpl的注入将失败,因为根据您的配置,将创建一个代理来应用 AOP。默认情况下使用接口,因为您正在实现一个接口,所以您的 bean 将是一个AnimalService但不是其中一个实现,这将是一个实现所有接口的动态代理。哪个,恕我直言,我应该像你应该对接口编程一样。 -
你是对的,如果我使用普通的java,仍然不能调用fly(),除非我像这样初始化bean:BirdServiceImpl birdService = new BirdServiceImpl();
标签: java spring spring-mvc