В интервью на весенних аннотациях, вы можете испытывать период смертельной цепи интервьюера спросил:
(1) @Configuration что толку?
(2) @Configuration и XML Какая разница? Что лучше?
(3) Spring основан на том, чтобы получить определение Бина? Как задержать инициализации Bean?
(4) @Autowired, @ Inject, в чем разница между @ ресурсами?
(5) @ Value, @ PropertySource 和 @Configuration?
(6) Как бороться с пружинными классов с @Configuration @Import из?
(7) @Profile что толку?
Как (8) @Configuration гнездо?
Как (9) модульное тестирование Spring проект?
Каковы ограничения (10) имеет по использованию @Configuration?
@Configuration основные инструкции
** Определение: указует объявление класса определяет один или несколько методов и @Bean единого управления Spring контейнер, таким образом, чтобы генерировать определение классов боба и запросы на обслуживание во время выполнения компонента. ** Например:
@ConfigurationpublicclassAppConfig {@BeanpublicMyBeanmyBean () {returnnewMyBean (); }}
Над AppConfig присоединиться @Configuration отмечает, что это класс конфигурации. Способ myBean () возвращает The MyBean () экземпляра, и аннотированный с @Bean, это указывает на то, что этот метод является необходимость управлять боба Спринг. @Bean Если вы не указали имя, а затем использовать myBean имя по умолчанию, которое строчное имя.
1. Начало Примечания
Запуская AnnotationConfigApplicationContext для руководства этой @Configuration аннотированные классы, такие как:
AnnotationConfigApplicationContext CTX = newAnnotationConfigApplicationContext (); ctx.register (AppConfig.class); ctx.refresh ();
В веб-проекте, вы можете также использовать AnnotationContextWebApplicationContext или другие варианты, чтобы начать.
SpringBoot новый проект (не спрашивайте меня, почему, потому что это быстрее, чтобы создать проект).
(1) pom.xml следующие документы
<? XML версия = "1.0" кодирование = "UTF-8"?> 4.0.0org.springframework.bootspring-загрузка-стартер-parent2.1.5.RELEASE <! - поиск родитель из репозитория -> com.spring.configurationspring -configuration0.0.1-SNAPSHOTspring-configurationDemo проект Spring Boot1.8org.springframework.bootspring-загрузки-стартер-testtestorg.springframeworkspring-context5.0.6.RELEASEorg.springframework.bootspring-загрузки Maven-плагин
Новый пакет в конфигурации MyConfiguration конфигурации окружающей среды, а также похож на пример кода выше, полный код выглядит следующим образом :
@ConfigurationpublicclassMyConfiguration {@BeanpublicMyBeanmyBean () {System.out.println ( "myBean Инициализирован"); returnnewMyBean (); }}
Описание MyConfiguration класс конфигурации, в состоянии управлять таким заявлением после нескольких Bean, мы объявляем MyBean фасоли, хотите, чтобы быть загружены и управления контейнером.
В новом пакете POJO MyBean конкретного кода класса следующим образом
publicclassMyBean {publicMyBean () {System.out.println ( "генерировать MyBean экземпляра"); } Publicvoidinit () {System.out.println ( "MyBean ресурсы Инициализирован"); }}
Создать SpringConfigurationApplication класс для класса тестирования MyConfiguration конкретного кода следующим образом :
publicclassSpringConfigurationApplication {publicstaticvoidmain (String [] арг) {// контекст AnnotationConfigApplicationContext = новый AnnotationConfigApplicationContext (MyConfiguration.class) // Поскольку мы загрузили @Configuration основывается на виде нот, так что вам нужно, чтобы создать контекст AnnotationConfigApplicationContextAnnotationConfigApplicationContext = newAnnotationConfigApplicationContext (); // Регистрация класс MyConfiguration и обновить контейнер для кофейных зерен. context.register (MyConfiguration.class); context.refresh ();}}
(2) Выход
myBean Initialized
генерировать MyBean Instance
Может быть видно из вывода результата, по умолчанию имя myBean загружается с контейнером для кофейных зерен загружаются , потому что myBean метод возвращает конструктор myBean, так myBean был инициализирован.
2. Запуск путем XML
Может быть определена с использованием XML вариант <контекст: аннотацию-конфигурации /> начинается с открытым аннотационный, а затем определить MyConfiguration боба, каталог / ресурсы нового кода приложения context.xml выглядит следующим образом :
<? XML версия = "1.0" кодирование = "UTF-8"?>
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd"><!-- эквивалент аннотацию на основе класса запуска AnnotationConfigApplicationContext-- >
Нужно ввести applicationContext.xml, мы должны быть включены SpringConfigurationApplication, SpringConfigurationApplication изменена следующим образом:
publicclassSpringConfigurationApplication {publicstaticvoidmain (String []) {арг ApplicationContext контекст = newClassPathXmlApplicationContext ( "applicationContext.xml"); }}
Выход:
myBean Initialized
генерировать MyBean Instance
На основе ComponentScan (), чтобы получить определение Bean
@Configuration оригинальная аннотаций для использования @Component, таким образом , @Configuration класс может также быть отсканированы в узел (в частности , использование XML контекста: Компонент скан - элемент).
Вот знаете , несколько заметок: @Controller, @Service, то @Repository, @Component
@Controller: аннотацию указывает, что класс является «контроллер», который является контроллером, можно понять, как шаблон MVC контроллер этой роли. Это специальный аннотаций @Component, оно позволяет сканировать с помощью сканирующего типа классов. Это, как правило, используется в сочетании с @RequestMapping комментарием.
@Service: указывает на то, что аннотированный класс представляет собой «Сервис», который является услуга слой, оно может быть понято как уровень режима обслуживания MVC эту роль, эта аннотация является особым @Component, позволяя класс реализации через путь к классу сканирования для сканирования
@Repository: указывает на то, что аннотированный класс является «Repository», команда реализован режим JavaEE, как может быть использован в качестве DAO в качестве «объекта доступа к данным», при использовании в сочетании с PersistenceExceptionTranslationPostProcessor, аннотированных классов имеют право на преобразование Spring цели. Это аннотации @Component определенной реализации, что позволяет классам быть автоматически сканируется
@Component: аннотацию указывает на то, что класс является компонентом, при использовании аннотаций на основе классов конфигурации и путь сканирования, эти классы считаются кандидатами для автоматического обнаружения.
Другими словами, вышеупомянутые четыре класса нот, отмеченных @ComponentScan, чтобы иметь возможность сканировать сцену и семантическую аннотацию большая разница является использование выше четырех не то же самое, например, вы хотите быть определение класса обслуживания для управления Spring, вы должны она определяется как @Service вместо @Controller класса, потому что мы семантически @ сервис больше как сервис, а не контроллер класса, @ компонент обычно называют компонентами, он может отметить у вас нет какой-либо строгой класса следует отметить, что, например, класс конфигурации, она не принадлежит к любому слою шаблона MVC, на этот раз, когда вы больше привыкли определять его как @Component. @ Контроллер, @ Service, @ Repository аннотацию на @Component имеет, таким образом, эти три ноты могут быть заменены @Component.
Посмотрите на код, чтобы понять:
Определяет пять классов, соответственно, основанные на @Controller, @Service, @Repository, @Component, @Configuration мечения, являются следующие
@ComponentpublicclassUserBean {} @ ConfigurationpublicclassUserConfiguration {} @ ControllerpublicclassUserController {} @ RepositorypublicclassUserDao {} @ ServicepublicclassUserService {} 复制 代码
На MyConfiguration @ComponentScan добавления аннотаций, сканирующее положение верхних пяти классов, где пакет. Код выглядит следующим образом:
@ Конфигурация @ ComponentScan (basePackages = "com.spring.configuration.pojo") publicclassMyConfiguration {@BeanpublicMyBeanmyBean () {System.out.println ( "myBean Инициализирован"); returnnewMyBean (); }} 复制 代码
SpringConfigurationApplication изменить код следующим образом:
publicclassSpringConfigurationApplication {publicstaticvoidmain (String [] арг) {// AnnotationConfigApplicationContext контекст = новый AnnotationConfigApplicationContext (MyConfiguration.class) // ApplicationContext контекст = новый ClassPathXmlApplicationContext ( "applicationContext.xml"); AnnotationConfigApplicationContext контекст = newAnnotationConfigApplicationContext (); context.register (MyConfiguration.class); context.refresh (); // 获取 启动 过程 中 的 боба 定义 的 名称 для (String STR: context.getBeanDefinitionNames ()) {System.out.println ( "ул =" + ул); } Context.close (); }} 复制 代码
Выход:
myBean Initialized
генерировать MyBean Instance
ул = org.springframework.context.annotation.internalConfigurationAnnotationProcessor
ул = org.springframework.context.annotation.internalAutowiredAnnotationProcessor
ул = org.springframework.context.annotation.internalRequiredAnnotationProcessor
ул = org.springframework.context.annotation.internalCommonAnnotationProcessor
ул = org.springframework.context.event.internalEventListenerProcessor
ул = org.springframework.context.event.internalEventListenerFactory
ул = myConfiguration
ул = UserBean
ул = USERCONFIGURATION
ул = UserController
ул = userDao
ул = UserService
ул = myBean
Может быть ясно видно из вывода, пяти классов, определенных выше @ComponentScan успешно отсканирована, и загружаются при запуске программы.
3. @Configuration 和 окружающей среды
Обычно используются с @Configuration средой, разрешенной по свойствам @Environment находятся в одном или более «атрибутах источника» объект, @ классы конфигурации может быть использованы @PropertySource свойства как объект обеспечивает источник среду
Для облегчения тестирования, мы полагаемся на введении junit4 и весенне-тест, после полного профиля
<? XML версия = "1.0" кодирование = "UTF-8"?> 4.0.0org.springframework.bootspring-загрузка-стартер-parent2.1.5.RELEASE <! - поиск родитель из репозитория -> com.spring.configurationspring -configuration0.0.1-SNAPSHOTspring-configurationDemo проект Spring Boot1.85.0.6.RELEASE4.3.13.RELEASE4.12org.springframework.bootspring-загрузки-стартер-testtestorg.springframeworkspring-контекст $ {spring.version} org.springframeworkspring-тест $ {} spring.test.version junitjunit $ {junit.version} org.springframework.bootspring-загрузочная Maven-плагин 复制 代码
Пакет определен в инъекционной конфигурации EnvironmentConfig класса собственности окружающей среды, полный код выглядит следующим образом:
@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (классы = EnvironmentConfig.class) @ Configuration @ PropertySource ( "путь к классам: beanName.properties") publicclassEnvironmentConfig {@AutowiredEnvironment окр; @TestpublicvoidtestReadProperty () {// получить свойство bean.name.controller System.out.println (env.getProperty ( "bean.name.controller")); // включающий определение того, bean.name.componentSystem.out.println (env.containsProperty ( "bean.name.component")); / / назад ключи, связанные с данным значением атрибута System.out.println (env.getRequiredProperty ( «bean.name.service»));}} скопировать код
Новые beanName.properties файлы в каталоге / ресурсов, следующим образом:
bean.name.configuration = beanNameConfigurationbean.name.controller = beanNameControllerbean.name.service = beanNameServicebean.name.component = beanNameComponentbean.name.repository = beanNameRepository 复制 代码
Запуск и тест Junit, выход заключается в следующем:
... .. ... ...
beanNameController
правда
beanNameService
... .. ... ...
Различение 4. @Autowired, @ Inject, @ Ресурс
@Inject: Это jsr330 спецификация достигается опираясь AutowiredAnnotationBeanPostProcessor инъекции класса. Javax.inject находится в пакете, являются собственные аннотации Java.
@ Inject @ Named ( "среда") Окружающая среда окр;
@Named без комментариев, вам нужно настроить с тем же именем переменной может быть.
@Autowired: @Autowired Spring аннотацию обеспечивается, достигается путем введения класса AutowiredAnnotationBeanPostProessor. Org.springframework.beans.factory.annotation пакет находится внутри, в Spring аннотаций
@AutowiredEnvironment ENV;
По умолчанию достигается путем введения ByType
@Resource: @Resource jsr250 спецификация реализуется, @ класс ресурсов CommonAnnotationBeanPostProcessor достигается путем инъекции. @Resource обычно указывается имя атрибута, как показано ниже:
@Resource (имя = «окружающая среда») Окружающая среда окр; дублируется код
По умолчанию достигается путем введения Byname
Разница:
@Autowired и @Inject по существу такой же, так как и используются для обработки зависимостей инъекции AutowiredAnnotationBeanPostProcessor. @Resource, но является исключением, она используется для обработки зависимостей инъекции CommonAnnotationBeanPostProcessor. Конечно, оба BeanPostProcessor.
После того, как введение в разнице между выше трех, атрибуты среды могут быть изменены в приведенном выше инъекции способом
@ Value, @ PropertySource 和 @Configuration
@Configuration может быть использован вместе @PropertySource @value и читать внешний профиль, используются следующим образом:
ReadValueFromPropertySource новый класс в пакете конфигурации, как показано ниже
@PropertySource ( "путь к классам: beanName.properties") @ ConfigurationpublicclassReadValueFromPropertySource {@value ( "bean.name.component") Струнный beanName; @Bean ( "myTestBean") publicMyBeanmyBean () {returnnewMyBean (beanName); }}
@PropertySource профиль представлен @value может получить значение атрибута, при методе myBean () указывает имя называется myTestBean.
MyBean модификации класса, добавляя имя атрибута и конструктор, который регенерированного метод ToString ()
Имя publicclassMyBean {Строка; publicMyBean (имя String) {this.name = имя; } PublicMyBean () {System.out.println ( "генерировать MyBean экземпляра"); } Publicvoidinit () {System.out.println ( "MyBean ресурсы Инициализирован"); } @OverridepublicStringtoString () {возвращение "MyBean {" + "имя = '" + имя + '\' '+'}'; }}
SpringConfigurationApplication испытываться следующим образом
publicclassSpringConfigurationApplication {publicstaticvoidmain (String [] арг) {// Для демонстрации целостности файла конфигурации, до того, как код не удаляется. // AnnotationConfigApplicationContext контекст = = новый AnnotationConfigApplicationContext (MyConfiguration.class) // ApplicationContext контекст = новый ClassPathXmlApplicationContext ( "applicationContext.xml"); // AnnotationConfigApplicationContext контекст = новый AnnotationConfigApplicationContext (); // context.register (MyConfiguration.class); / / context.refresh (); //// // Получаем имя процесса боб запуска определение // для (ул Струнный: context.getBeanDefinitionNames ()) {// System.out.println ( "ул =" + ул ); //} // context.close (); ApplicationContext контекст = newAnnotationConfigApplicationContext (ReadValueFromPropertySource.class); myBean myBean = (myBean) context.getBean ( "
Использование аппликаций @ InConntext может получить myTestBean боб, а затем создать экземпляр myBean.
输出: myBean = MyBean {имя = 'bean.name.component'}
5. @Import 和 @Configuration
@Import определен (от JavaDoc): указывает на то, что один или больше нужно импортировать класс конфигурации, весна XML-обеспечивают эквивалентные функциональные возможности, позволяющие импорт @Configuration, @ ImportSelector, @ ImportBeanDefinitionRegistar достигнуто и тому подобные обычные компоненты AnnotationConfigApplicationContext. Можно на уровне класса или оригинальный комментарий. Если Bean ресурсы, необходимые X или другой не- знак @ конфигурации импортируются, используйте @ImportResource. Ниже приведен пример кода:
В двух новых пакета конфигурации классов Pojo, а именно CustomerBo, SchedualBo
@ConfigurationpublicclassCustomerBo {publicvoidprintMsg (String тзд) {System.out.println ( "CustomerBo:" + MSG); } @BeanpublicCustomerBotestCustomerBo () {returnnewCustomerBo (); }} @ ConfigurationpublicclassSchedulerBo {publicvoidprintMsg (String Msg) {System.out.println ( "SchedulerBo:" + тзд); } @BeanpublicSchedulerBotestSchedulerBo () {returnnewSchedulerBo (); }} 复制 代码
Создать новый пакет в конфигурации AppConfig введенной CustomerBo и SchedulerBo.
@ Конфигурация @ Импорт (значение = {CustomerBo.class, SchedulerBo.class}) publicclassAppConfig {}
В новом пакете ImportWithConfiguration конфигурации, для использования в тестировании @Import и @Configuration
publicclassImportWithConfiguration {publicstaticvoidmain (String []) {арг ApplicationContext контекст = newAnnotationConfigApplicationContext (AppConfig.class); CustomerBo customerBo = (CustomerBo) context.getBean ( "testCustomerBo"); customerBo.printMsg ( "Система из Println ( 'получить от customerBo')"); SchedulerBo schedulerBo = (SchedulerBo) context.getBean ( "testSchedulerBo"); schedulerBo.printMsg ( "Система из Println ( 'получить от schedulerBo')"); }}
Выход:
CustomerBo: Система из Println ( 'получить от customerBo')
SchedulerBo: Система из Println ( 'получить от schedulerBo')
@Профиль
@Profile: указывает, когда один или более из указанного профиля @value доступен, компоненты отвечают могут быть зарегистрированы условия регистрации.
Набор из трех способов:
() Может быть активирован в запрограммированном образом с помощью ConfigurableEnvironment.setActiveProfiles
По AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME (spring.profiles.active) собственности
JVM недвижимости
В качестве переменной среды, или в качестве параметра сервлетов web.xml контекста приложения. Вы также можете активировать @ActiveProfiles декларативно комментария в интеграционном тестировании файла конфигурации.
сфера
В аннотации на уровне класса, или непосредственно в любом типе @Component связанного класс включает @Configuration
Как оригинальные заметки, примечания могут быть настроены
В качестве метода аннотаций роли в любом методе
Примечание :
Если профиль с использованием метки профиля класса или @Profile роли должен быть включен, чтобы вступить в силу в любом классе, если @Profile ({ «p1», «! P2»}) определяет два атрибута, то p1 включен и p2, не включенное состояние.
6. @ImportResource 和 @Configuration
@ImportResource: Эта аннотация обеспечивает аналогичную функцию с @Import роли, часто используется с @Configuration, были инициированы AnnotationConfigApplicationContext, смотрите ниже на конкретном примере использования:
Новый класс TestService в конфигурации, объявить конструктор вызывается при инициализации класса
publicclassTestService {publicTestService () {System.out.println ( "тест успех @importResource"); }}
В новом каталоге importResources.xml / ресурсов для того, чтобы ввести TestService
<? XML версия = "1.0" кодирование = "UTF-8"?>
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd «> Скопировать код
Тогда новый ImportResourceWithConfiguration в конфигурации, для чтения файла конфигурации
@ Конфигурации @ ImportResource ( "Путь к классам: importResources.xml") publicclassImportResourceWithConfiguration {@AutowiredprivateTestService обслуживание; publicvoidgetImportResource () {newTestService (); } Publicstaticvoidmain (String [] арг) {AnnotationConfigApplicationContext контекст = newAnnotationConfigApplicationContext (ImportResourceWithConfiguration.class); context.getBean ( "TestService"); }}
Выход: тест успех @importResource
7. @Configuration Уплотненный
@Configuration аннотации действует на классе, а общий класс, как могут быть вложены друг в друга, определяет внутренний класс.
// 来自 JavaDoc @ ConfigurationpublicclassAppConfig {@InjectDataSource DataSource; @BeanpublicMyBeanmyBean () {returnnewMyBean (DataSource); } @ConfigurationstaticclassDataConfig () {@ BeanDataSourcedataSource () {returnnewEmbeddedDatabaseBuilder (). Строить ()}}}
В приведенном выше коде, только вам нужно зарегистрироваться AppConfig в контексте применения. Поскольку классы являются вложенными @Configuration, DatabaseConfig автоматически регистрируется. Когда отношения между AppConfig, DatabaseConfig явно подразумевает, что исключает необходимость использования @Import аннотаций.
@Lazy Отложенная инициализация
@Lazy: боб указать, является ли нагрузка задержки, может действовать по способу, этот способ показывает загрузку с задержкой; @Component может действовать на (как оригинал или аннотированный в @Component) аннотация на основе, указывая, что этот класс все фасоль лениться загрузки. Если нет ни одного комментария @Lazy или @Lazy установлен в ложь, то компонент будет загружен насущным желание, в дополнении к выше двух областям, @ Ленивые могут также действовать от свойств и @Inject @Autowired аннотаций, в которых случай, он создает инертный агент, который поле, как метод по умолчанию ObjectFactory или поставщика. Давайте покажем вам:
Изменить класс MyConfiguration, добавив @Lazy аннотацию на классе, добавить метод IfLazyInit (), чтобы проверить, является ли инициализирован.
@ Ленивый @ Конфигурация @ ComponentScan (basePackages = "com.spring.configuration.pojo") publicclassMyConfiguration {@BeanpublicMyBeanmyBean () {System.out.println ( "myBean Инициализирован"); returnnewMyBean (); } @BeanpublicMyBeanIfLazyInit () {System.out.println ( "инициализируется"); returnnewMyBean (); }} 复制 代码
Перед внесением изменений в SpringConfigurationApplication класс запуска, открытый MyConfiguration начать занятия
publicclassSpringConfigurationApplication {publicstaticvoidmain (String [] арг) {контекст AnnotationConfigApplicationContext = newAnnotationConfigApplicationContext (MyConfiguration.class); // ApplicationContext контекст = новый ClassPathXmlApplicationContext ( "applicationContext.xml"); // AnnotationConfigApplicationContext контекст = новый AnnotationConfigApplicationContext (); // context.register (MyConfiguration.class); // context.refresh (); // //// 获取 启动 过程 中 的 боба 定义 的 名称 для (String STR: context.getBeanDefinitionNames ()) {System.out.println ( "ул = «+ ул); } // context.close (); // ApplicationContext контекст = // новый AnnotationConfigApplicationContext (ReadValueFromPropertySource.class); // MyBean myBean = (MyBean) context.getBean ( "myTestBean");
Вы не найдете вывод определения информации о компоненте, но когда он @Lazy комментариев удалены, вы найдете информацию о выходе инициализации боба:
myBean Initialized
генерировать MyBean Instance
инициализируется
генерировать MyBean Instance
8. @RunWith 和 @ContextConfiguration
Junit4 тестовый класс для аннотаций представляют испытания на Junit4, можно начать писать код класса опущен, и т.п. заменен ApplicationContext начать занятие в классе. Обычно для модульного тестирования и @RunWith @Configuration, что имеет важное значение в процессе разработки программного обеспечения и имеет часть профессиональной выше EnvironmentConfig подтверждает этот класс:
@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (классы = EnvironmentConfig.class) @ Configuration @ PropertySource ( "путь к классам: beanName.properties") publicclassEnvironmentConfig {// @ Autowired // Окружающая среда окр; @InjectEnvironment Env; @TestpublicvoidtestReadProperty () {/ / System.out.println bean.name.controller приобретения атрибута (env.getProperty ( "bean.name.controller")); // включающий определение того, bean.name.componentSystem.out.println (env.containsProperty ( «бобовые .name.component ")); // возвращает атрибуты, связанные с заданным значением ключа System.out.println (env.getRequiredProperty (" bean.name.service «));}}
9. @Enable начать пружине встроенные функции
Подробности Проверка @ EnableAsync, @ EnableScheduling, @ EnableTransactionManagement, @ EnableAspectJAutoProxy, @ EnableWebMvc официальных документов
10. @Configuration ограничения использования
Она должна быть обеспечена таким же образом (то есть, примеры не возвращаются из заводского способа)
@Configuration аннотированный классы должны быть не окончательным
Класс конфигурации должен быть не локальным (т.е. способ не может быть объявлена), нативный метод маркировки
Любой вложенный @Configuration должен быть статика.
@Bean метод не может в свою очередь, создаст дополнительный класс конфигурации