仅出于教育原因,我正在尝试探索使用注释或XML配置与DI的区别。
为了做到这一点,我有一个Messager应用程序的例子,它可以使用不同的实现来做不同类型的工作(发送电子邮件,发送短信)。
使用测试类我可以从工厂获取bean,如果需要,可以注入不同的实现。
它的外观如下:
IMessageService.java
public interface IMessageService {
public void sendMessage(String message, String recipient);
}
EmailMessageServiceImpl.java
public class EmailMessageServiceImpl implements IMessageService {
@Override
public void sendMessage(String message, String recipient) {
//Validations email, etc.
System.out.println(String.format("EMAIL Message: %s. Recipient: %s", message, recipient));
}
}
SMSMessageServiceImpl.java
public class SMSMessageServiceImpl implements IMessageService {
@Override
public void sendMessage(String message, String recipient) {
//Phone validations
System.out.println(String.format("SMS message: %s. Sent to: %s", message, recipient));
}
}
App.java
public class App {
private IMessageService messageService;
public void processMessages(String message, String recipient) {
messageService.sendMessage(message, recipient);
}
public void setMessageService(IMessageService messageService) {
this.messageService = messageService;
}
}
的applicationContext.xml
<!-- Declaring the App and injecting two different implementations of IMessageService-->
<bean id="appEmail" class="org.invenio.tic.holamundospring.App">
<property name="messageService" ref="emailImpl"/>
</bean>
<bean id="appSMS" class="org.invenio.tic.holamundospring.App">
<property name="messageService" ref="smsImpl"/>
</bean>
<!-- Declaring the beans with the implementations-->
<bean id="emailImpl" class="org.invenio.tic.holamundospring.service.EmailMessageServiceImpl"/>
<bean id="smsImpl" class="org.invenio.tic.holamundospring.service.SMSMessageServiceImpl"/>
最后是测试课 Main.java
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
App app = (App) context.getBean("appEmail");
app.processMessages("Hi, this is an email", "info@invenio.org");
app = (App) context.getBean("appSMS");
app.processMessages("This is an SMS", "88100452");
}
}
打印:
EMAIL Message: Hi, this is an email. Recipient: info@invenio.org
SMS message: This is an SMS. Sent to: 88100452
当我尝试使用Annotations,使用Spring的自动装配和自动发现功能时,我失去了使用不同实现获取应用程序的能力,因为Annotation @Autowired让我选择我想要的实现,但它将被硬编码到App.java类。
App.java
@Component
public class App {
@Autowired
@Qualifier("emailServiceImpl")
private IMessageService messageService;
public void processMessages(String message, String recipient) {
messageService.sendMessage(message, recipient);
}
public void setMessageService(IMessageService messageService) {
this.messageService = messageService;
}
}
有没有解决这个问题的方法?比如在参数中传递限定符名称,或者让我在运行时更改MessageService的实现?
或者这是使用Annotations的缺点之一吗?
由于 -Alejandro。
答案 0 :(得分:0)
尝试将@Qualifier("emailServiceImpl")
更改为@Qualifier("emailImpl")
,就像在applicationContext.xml中定义一样。
答案 1 :(得分:0)
你可以使用这样的app构造函数来完成它:
配置类:
@Configuration
@ComponentScan("com.anno") //your package goes here
public class Config {
@Bean(name = "appEmail")
public App appEmail(@Qualifier("EmailMessageServiceImpl") IMessageService messageService) {
return new App(messageService);
}
@Bean(name = "appSMS")
public App appSms(@Qualifier("SMSMessageServiceImpl") IMessageService messageService) {
return new App(messageService);
}
}
App类:
@Component
public class App {
private IMessageService messageService;
public App() {
}
public App(IMessageService messageService) {
this.messageService = messageService;
}
public void processMessages(String message, String recipient) {
messageService.sendMessage(message, recipient);
}
public void setMessageService(IMessageService messageService) {
this.messageService = messageService;
}
}
服务类:
@Service("SMSMessageServiceImpl")
public class SMSMessageServiceImpl implements IMessageService {
public void sendMessage(String message, String recipient) {
// Phone validations
System.out.println(String.format("SMS message: %s. Sent to: %s", message, recipient));
}
}
@Service("EmailMessageServiceImpl")
public class EmailMessageServiceImpl implements IMessageService {
public void sendMessage(String message, String recipient) {
// Validations email, etc.
System.out.println(String.format("EMAIL Message: %s. Recipient: %s", message, recipient));
}
}
主要类别:
public class Main {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
App app = (App) context.getBean("appEmail");
app.processMessages("Hi, this is an email", "info@invenio.org");
app = (App) context.getBean("appSMS");
app.processMessages("This is an SMS", "88100452");
}
}
希望这可以提供帮助。