Я собираюсь продемонстрировать профили и аннотацию @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
|
@Test public 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 value spring.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
|
@Test public 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
|
@Test public 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 .