简体   繁体   English

Spring默认配置有Profile

[英]Spring default wiring with Profile

I've got two beans. 我有两个豆子。 Both implement the mailing function. 两者都实现了邮件功能。 One is only working when it is deployed to an application server. 一个仅在部署到应用程序服务器时才起作用。 The other one is used for testing. 另一个用于测试。

We have profile for each developer and environment. 我们为每个开发人员和环境提供配置文件 I want to wire the testing bean only when actually testing. 我想在实际测试时才连接测试bean。 The other bean should be used when not testing. 不测试时应该使用另一个bean。 How can I archive this? 我该如何存档?

@Component
@Profile("localtest")
public class OfflineMail implements Mailing {}

Solution approaches: 解决方法:

Using "default" I read this somewhere, but there seems to be no fall-back to "default" for a profile like "dev": 使用“默认”我在某处读到了这个内容,但对于像“dev”这样的配置文件似乎没有回退到“默认”:

@Component
@Profile("default")
public class OnlineMail implements Mailing {}

-> Exception for no bean for wiring found. - >没有找到布线的bean的例外情况。

Leaving the profile out: 离开个人资料:

@Component
public class OnlineMail implements Mailing {}

-> Throws a unique exception when running the "localtest" profile. - >运行“localtest”配置文件时引发一个唯一的异常。

Adding all profiles: 添加所有档案:

@Component
@Profile("prod")
@Profile("integration")
@Profile("test")
@Profile("dev1")
@Profile("dev2")
@Profile("dev3")
...
public class OnlineMail implements Mailing {}

This is actually working, however our devs aren't numbered they use "dev<WindowsLogin>" and adding the profiles, may work for one bean, but one will get into trouble when using it for several beans as this definitely gets ugly. 这实际上是有效的,但是我们的开发人员没有编号,他们使用“dev <WindowsLogin>”并添加配置文件,可能适用于一个bean,但是当一个bean使用它时会遇到麻烦,因为这肯定会变得很难看。

Using something like @Profile("!localtest") doesn't seem to work as well. 使用类似@Profile(“!localtest”)的东西似乎也不行。

Does anyone know a nicer way to get a "wire by default if no specific bean is found"? 有没有人知道更好的方法来获得“如果没有找到特定的bean,默认连线”?

I finally found an easy solution. 我终于找到了一个简单的方法。

The online mail is just wired by default. 默认情况下,在线邮件刚刚连线。

@Component
public class OnlineMail implements Mailing {}

Using the @Primary annotation the offline mail takes precedence over the OnlineMail and avoids the Unique exception. 使用@Primary注释,脱机邮件优先于OnlineMail,并避免使用Unique异常。

@Component
@Profile("localtest")
@Primary
public class OfflineMail implements Mailing {}

Try this: 尝试这个:

@Component
@Profile("production")
public class OnlineMail implements Mailing {}

@Component
@Profile("localtest")
public class OfflineMail implements Mailing {}

Then run tests using @ActiveProfiles("localtest") and run production enviroment using "production" as DEFAULT profile. 然后使用@ActiveProfiles(“localtest”)运行测试,并使用“production”作为DEFAULT配置文件运行生产环境。

Also I hope in next version of Spring ActiveProfilesResolver will be introduced SPR-10338 - it may be helpfull for you (to avoid "dev1", "dev2" and so on). 另外我希望在下一版本的Spring ActiveProfilesResolver中引入SPR-10338 - 它可能对你有所帮助(避免“dev1”,“dev2”等)。

Spring supports inject the Bean by @Profile very well: Spring支持很好地通过@Profile注入Bean:

interface Talkative {
    String talk();
}

@Component
@Profile("dev")
class Cat implements Talkative {
        public String talk() {
        return "Meow.";
    }
}

@Component
@Profile("prod")
class Dog implements Talkative {
    public String talk() {
        return "Woof!";
    }
}

Works in unit test 适用于单元测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContex-test.xml"})
@ActiveProfiles(value = "dev")
public class InjectByDevProfileTest
{
    @Autowired
    Talkative talkative;

    @Test
    public void TestTalkative() {
        String result = talkative.talk();
        Assert.assertEquals("Meow.", result);

    }
}

Works in Main(): 在Main()中工作:

@Component public class Main { @Component公共类Main {

        public static void main(String[] args) {
            // Enable a "dev" profile
            System.setProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, "dev");
            ApplicationContext context =
                    new ClassPathXmlApplicationContext("applicationContext.xml");
            Main p = context.getBean(Main.class);
            p.start(args);
        }

        @Autowired
        private Talkative talkative;

        private void start(String[] args) {
            System.out.println(talkative.talk());
        }
    }

Check this for the Demo code: https://github.com/m2land/InjectByProfile 检查这个演示代码: https//github.com/m2land/InjectByProfile

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM