Интервьюер ребенок не знает, что оказалось, что я не понимаю, весной @Configuration

В интервью на весенних аннотациях, вы можете испытывать период смертельной цепи интервьюера спросил:

(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 метод не может в свою очередь, создаст дополнительный класс конфигурации

рекомендация

отblog.csdn.net/mifffy_java/article/details/91948377