Java springdi:从XML到注释

Java springdi:从XML到注释,java,spring,dependency-injection,annotations,Java,Spring,Dependency Injection,Annotations,仅出于教育目的,我试图探索在Spring中使用DI的注释或XML配置之间的差异 为了做到这一点,我举了一个Messager应用程序的例子,它可以使用不同的实现来完成不同类型的工作(发送电子邮件、发送短信) 使用一个测试类,我可以从工厂得到一个bean,如果我想的话,可以注入一个不同的实现 这就是它的样子: IMessageService.java public interface IMessageService { public void sendMessage(Stri

仅出于教育目的,我试图探索在Spring中使用DI的注释或XML配置之间的差异

为了做到这一点,我举了一个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));
    }

}
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));
    }

}
SMSMessageServiceImpl.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));
    }

}
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;
        }

}
    @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;
    }

}
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"/>
这张照片是:

    EMAIL Message: Hi, this is an email. Recipient: info@invenio.org
    SMS message: This is an SMS. Sent to: 88100452
当我尝试使用Spring的Autowiring和Autodiscovery功能对注释执行此操作时,我失去了获得具有不同实现的应用程序的能力,因为注释@Autowired允许我选择我想要的实现,但它将被硬编码到App.java类

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;
        }

}
    @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的实现

或者这是使用注释的缺点之一

谢谢
-Alejandro.

尝试将
@Qualifier(“emailServiceImpl”)
更改为
@Qualifier(“emailImpl”)
,正如您在applicationContext.xml中定义的那样。

您可以使用如下应用程序构造函数:

配置类:

@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);
    }
}
@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");

}

}
应用程序类:

@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);
    }
}
@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");

}

}
服务类别:

@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);
    }
}
@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");

}

}
主类:

@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);
    }
}
@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");

}

}

希望这能有所帮助。

一旦我开始使用注释,所有bean定义都将从xml中删除,因为我使用了自动发现功能: