Я собираюсь продемонстрировать профили и аннотацию @Configuration с помощью класса Person из моего предыдущего блога. Это простой класс компонентов, свойства которого различаются в зависимости от того, какой профиль активен.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public class Person { private final String firstName; private final String lastName; private final int age; public Person(String firstName, String lastName, int age) { this.firstName = firstName; this.lastName = lastName; this.age = age; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public int getAge() { return age; } } |
Помните, что ребята из Spring рекомендуют использовать профили Spring только тогда, когда вам нужно загрузить разные типы или наборы классов, и что для установки свойств вы должны продолжать использовать PropertyPlaceholderConfigurer . Причина, по которой я нарушаю правила, заключается в том, что я хочу попробовать написать самый простой код, демонстрирующий профили и конфигурацию Java.
В основе использования профилей Spring с настройкой Java лежит новая аннотация Spring @Profile . Аннотация @Profile используется для прикрепления имени профиля к примечанию @Configuration . Он принимает один параметр, который можно использовать двумя способами. Во-первых, чтобы прикрепить один профиль к аннотации @Configuration :
|
1
|
@Profile("test1") |
и во-вторых, чтобы прикрепить несколько профилей:
|
1
|
@Profile({ "test1", "test2" }) |
Опять же, я собираюсь определить два профиля «test1» и «test2» и связать каждый из них с файлом конфигурации. Сначала «test1»:
|
01
02
03
04
05
06
07
08
09
10
|
@Configuration@Profile("test1") public class Test1ProfileConfig { @Bean public Person employee() { return new Person("John", "Smith", 55); } } |
… А затем «test2»:
|
01
02
03
04
05
06
07
08
09
10
|
@Configuration@Profile("test2") public class Test2ProfileConfig { @Bean public Person employee() { return new Person("Fred", "Williams", 22); } } |
В приведенном выше коде вы можете видеть, что я создаю bean-компонент Person с эффективным id сотрудника (это из имени метода), который возвращает разные значения свойств в каждом профиле.
Также обратите внимание, что @Profile помечен как:
|
1
|
@Target(value=TYPE) |
… Что означает, что его можно поместить только рядом с аннотацией @Configuration .
Прикрепив @Profile к @Configuration , вы должны активировать выбранный @Profile . При этом используются те же принципы и методы, которые я описал в своем последнем блоге, и, опять же, на мой взгляд, наиболее полезный метод активации заключается в использовании системного свойства «spring.profiles.active».
|
01
02
03
04
05
06
07
08
09
10
|
@Testpublic void testProfileActiveUsingSystemProperties() { System.setProperty("spring.profiles.active", "test1"); ApplicationContext ctx = new ClassPathXmlApplicationContext("profiles-config.xml"); Person person = ctx.getBean("employee", Person.class); String firstName = person.getFirstName(); assertEquals("John", firstName); } |
Очевидно, что вы не захотите жестко кодировать вещи, как я делал выше, и наилучшая практика обычно подразумевает сохранение конфигурации системных свойств отдельно от вашего приложения. Это дает вам возможность использовать простой аргумент командной строки, такой как:
|
1
|
-Dspring.profiles.active="test1" |
… или добавив
|
1
2
|
# Setting a property valuespring.profiles.active=test1 |
к кошке Tomcat's.properties
Итак, это все, что нужно сделать: вы создаете свои профили Spring, аннотируя @Configuration аннотацией @Profile, а затем переключая профиль, который вы хотите использовать, устанавливая системное свойство spring.profiles.active на имя вашего профиля. ,
Как обычно, ребята в Spring не просто ограничивают использование системных свойств для активации профилей, вы можете делать это программно. Например, следующий код создает AnnotationConfigApplicationContext, а затем использует объект Environment для активации профиля «test1» перед регистрацией наших классов @Configuration .
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
@Testpublic void testAnnotationConfigApplicationContextThatWorks() { // Can register a list of config classes AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.getEnvironment().setActiveProfiles("test1"); ctx.register(Test1ProfileConfig.class, Test2ProfileConfig.class); ctx.refresh(); Person person = ctx.getBean("employee", Person.class); String firstName = person.getFirstName(); assertEquals("John", firstName); } |
Это все хорошо, но будьте осторожны, вам нужно вызывать методы AnnotationConfigApplicationContext в правильном порядке. Например, если вы зарегистрируете свои классы @Configuration до того, как укажете свой профиль, вы получите исключение IllegalStateException .
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
@Test(expected = IllegalStateException.class) public void testAnnotationConfigApplicationContextThatFails() { // Can register a list of config classes AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext( Test1ProfileConfig.class, Test2ProfileConfig.class); ctx.getEnvironment().setActiveProfiles("test1"); ctx.refresh(); Person person = ctx.getBean("employee", Person.class); String firstName = person.getFirstName(); assertEquals("John", firstName); } |
Перед закрытием сегодняшнего блога приведенный ниже код демонстрирует возможность прикрепления нескольких @Profiles к аннотации @Configuration .
|
01
02
03
04
05
06
07
08
09
10
|
@Configuration@Profile({ "test1", "test2" }) public class MulitpleProfileConfig { @Bean public Person tourDeFranceWinner() { return new Person("Bradley", "Wiggins", 32); } } |
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
@Testpublic void testMulipleAssignedProfilesUsingSystemProperties() { System.setProperty("spring.profiles.active", "test1"); ApplicationContext ctx = new ClassPathXmlApplicationContext("profiles-config.xml"); Person person = ctx.getBean("tourDeFranceWinner", Person.class); String firstName = person.getFirstName(); assertEquals("Bradley", firstName); System.setProperty("spring.profiles.active", "test2"); ctx = new ClassPathXmlApplicationContext("profiles-config.xml"); person = ctx.getBean("tourDeFranceWinner", Person.class); firstName = person.getFirstName(); assertEquals("Bradley", firstName); } |
В приведенном выше коде победитель Тур де Франс 2012 года Брэдли Уиггинс появляется в профилях «test1» и «test2».
Ссылка: Spring, Enterprise Java от нашего партнера по JCG Роджера Хьюза в блоге Captain Debug’s Blog .