根据dev / test / prod模式更改Spring电子邮件设置

时间:2010-01-24 12:45:51

标签: java spring email smtp

我经常使用实时数据库的副本测试我的应用程序,但必须小心不要执行任何导致将电子邮件发送给用户的操作。我希望有一种配置弹簧的方法,这样当我处于开发或测试模式时,没有电子邮件会被发送给真实用户。理想情况下,我希望所有应该转到用户的电子邮件转到我可以检查的邮箱。而且我不想更改任何代码来实现这一点,只需要xml配置文件。

我已经在使用PropertyPlaceholderConfigurer并且正在读取基于我是否在生产,测试或开发模式下运行的不同属性文件。我根据属性文件中的值配置JavaMailSenderImpl。我也使用SimpleMailMessage创建一个带有From地址的模板。

如果我在开发或测试模式下运行,理想情况下会有一种方法可以重写到测试帐户的所有外发电子邮件的TO地址。

我的第一个想法是使用不同的SMTP服务器进行开发和测试。但是,我还必须管理另一个邮件服务器,并且需要对其进行自定义,以便它不会将邮件发送到任何地方,而是将其发送到单个邮箱。如果可能,我不想添加更多管理要求。

也许这是最好的解决方案,但似乎应该有一种拦截电子邮件和更改收件人的方法。

之前有没有人处理过这个问题?你想出了什么解决方案?

6 个答案:

答案 0 :(得分:4)

注意:我的回答是以使用Maven为基础的,所以这更多是关于构建而不是任何东西,但是使用spring可以方便地注入值。

我使用property-placeholder并构建如下的bean:

jdbc.properties:

db.url=hostname:1521/test
db.username=awesome
db.password=password

applicationContext.xml(使用上下文命名空间)

<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="yo" class="some.DataSource">
    <property name="url" value="${db.url}"/>
    <property name="username" value="${db.username}"/>
    <property name="password" value="${db.password}"/>
</bean>

然后,我将环境存储在具有特定于域的值的单独文件夹中,如:

src/main/environments
 ++ prod
 +++++ jdbc.properties
 ++ dev
 +++++ jdbc.properties
 ++ cert
 +++++ jdbc.properties

使用maven配置文件(来自pom.xml):

<profile>
    <id>environment</id>
    <activation>
        <property>
            <name>environment</name>
        </property>
    </activation>
    <build>
        <resources>
            <resource>
                <directory>src/main/environments/${environment}</directory>
            </resource>
        </resources>

您可以使用-Denviroment属性运行任何maven命令来灵活属性:

mvn clean -Denvironment=dev test
mvn clean -Denvironment=cert package
mvn clean -Denvironment=prod deploy

等。并且该环境文件夹中的任何文件都会与任何src / main / resources文件一起复制到目标或工件中。

答案 1 :(得分:2)

我过去有过类似的要求,我的解决方案是编写我称之为EnvironmentSelectingFactoryBean的内容(Spring似乎鼓励长名字......)。这是一个FactoryBean实现,它将根据当前的应用程序环境“选择”一系列可用bean。

如果我向您展示一些XML示例,我想您会明白这一点:

<bean id="mailSender" class="com.kizoom.spring.config.EnvironmentSelectingFactoryBean">
   <property name="beanMap">
      <map>
         <entry key="test">
            <bean class="org.springframework.mail.javamail.JavaMailSenderImpl">
               <property name="host" value="${mailhost.test}"/>
            </bean>
         </entry>
         <entry key="production">
            <bean class="org.springframework.mail.javamail.JavaMailSenderImpl">
               <property name="host" value="${mailhost.production}"/>
            </bean>
         </entry>
      </map>
   </property>
</bean>

因此,EnvironmentSelectingFactoryBean知道您是在“测试”还是“生产”模式下运行,从beanMap中选择适当的bean,然后从FactoryBean.getObject()方法中调出它们。 beanMap中的两个bean都是真正的邮件发件人,而不是存根,每个都有不同的proprty占位符值,但是你永远不会冒错误的风险。

客户端代码只会看到一个JavaMailSender bean。

答案 2 :(得分:1)

我看到您声明了一个特定的要求,即您不想更改任何代码。我仍然建议创建JavaMailSender的存根实现。这样,您可以在开发和测试构建中注入存根对象。

答案 3 :(得分:1)

请查看mock-javamail(以前的答案建议的内容)或可能更快的解决方案是假的SMTP服务器,如Fakemail

答案 4 :(得分:1)

Property Place holder的另一个选项是在运行时根据System属性动态加载属性文件。

                     /WEB-INF/config/myapp.${myapp.env}.properties              

WEB-INF / conf将有 myapp.prod.properties myapp.stag.properties myapp.test.properties

将-Dmyapp.env = prod添加到tomcat或您的应用程序服务器启动脚本。

答案 5 :(得分:1)

最佳解决方案是将javax.mail.Session创建为JNDI资源。您可以为 prod / 测试 dev 设置不同的设置。而且您不必担心更改应用中的设置,因为只有差异由服务器管理。

对于开发*和**测试,我可以向您推荐javax.mail.Session的好模拟。

github项目 javaMail extension 添加文件传输,允许:

  • text格式将邮件保存到文件而不是发送
  • mbox格式将邮件保存到文件而不是发送
  • 添加日志信息而不是发送电子邮件