@Импортировать аннотацию
@Import
Аннотации предоставляются и в XML<import/>
Эквивалентная функциональность элемента, которая реализует один или несколько импортированных классов конфигурации.@Import
То есть его можно использовать в классе или в качестве мета-аннотации.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
/**
* {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar}
* or regular component classes to import.
*/
Class<?>[] value();
}
В аннотации только одинvalue();
. Поддержка импорта@Configuration
Аннотированный класс конфигурации, реализующийImportSelector
класс, реализация интерфейсаImportBeanDefinitionRegistrar
класс интерфейса и обычный@component
Добрый.
Использовать как мета-аннотацию
@Import
Может использоваться как мета-аннотация, которую можно найти в@Import
Наследование инкапсулирует слой. Насколько я понимаю, это не будет раскрывать детали моей внутренней реализации внешнему миру (используя сторону).
Например: напр.@EnableAspectJAutoProxy
аннотация.
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
@EnableAspectJAutoProxy
должна быть@Import
Эта мета-аннотация отмечает, что мы (программисты), используя@EnableAspectJAutoProxy
Чтобы открыть AspectJAutoProxy и нижний слой Spring через@Import
Представляем соответствующую конфигурацию для достижения класса.
Импортировать класс, реализующий интерфейс ImportSelector.
Давайте взглянемImportSelector
интерфейс, который имеет только один метод:
public interface ImportSelector {
String[] selectImports(AnnotationMetadata importingClassMetadata);
}
ImportSelector, селектор ввода. Этот интерфейс используется для выбора классов конфигурации для импорта в зависимости от заданных условий.
Например: напр.@EnableTransactionManagement
аннотация.
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
существует@EnableTransactionManagement
используется в аннотации@Import(TransactionManagementConfigurationSelector.class)
аннотация, котораяTransactionManagementConfigurationSelector
класс реализованImportSelector
интерфейс.
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
return new String[] {AutoProxyRegistrar.class.getName(),
ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[] {
TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
default:
return null;
}
}
}
Внутренняя логика реализации метода также очень проста, т.е.AdviceMode
Импортируйте различные классы конфигурации для реализации управления транзакциями.
Импортировать класс, реализующий интерфейс ImportBeanDefinitionRegistrar.
ImportBeanDefinitionRegistrar
В интерфейсе тоже только один метод:
public interface ImportBeanDefinitionRegistrar {
void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);
}
Этот интерфейс позволяет нам регистрировать дополнительные аннотации по запросу на основе заданных метаданных аннотаций.BeanDefinition
.
Например: напр.@EnableAspectJAutoProxy
аннотация.
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
@EnableAspectJAutoProxy
Аннотация представляетAspectJAutoProxyRegistrar.class
класс, этот класс реализованImportBeanDefinitionRegistrar
интерфейс.
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
registerBeanDefinitions
позвонил вAopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
метод, этот метод проходит вBeanDefinitionRegistry registry
зарегистрирован вBeanDefinition
. зарегистрированBeanDefinition
После этого Spring создаст экземпляр Bean, чтобы получить роль AspectJAutoProxy.
Импортировать класс @Configuration
этот раз@Import
Наиболее распространенным является способ использования. Мы можем разделить класс конфигурации, а затем импортировать соответствующую конфигурацию по мере необходимости в программу.
Например: напр.@EnableRetry
аннотация.
Используйте эту аннотацию, чтобы включить функцию повтора.
@EnableAspectJAutoProxy(proxyTargetClass = false)
@Import(RetryConfiguration.class)
public @interface EnableRetry {
Он импортируется внутрьRetryConfiguration
Этот класс конфигурации.
Интерфейс ImportAware
ImportAware
Интерфейс требуется и@Import
Используется вместе. существует@Import
При использовании в качестве мета-аннотации передать@Import
Если импортированный класс конфигурации реализованImportAware
Интерфейс может получить конфигурацию данных, импортированную в интерфейс класса конфигурации. Это немного запутанно, давайте перейдем непосредственно к коду.
Например:@EnableAsync
аннотация.
@Import(AsyncConfigurationSelector.class)
public @interface EnableAsync {
//AsyncConfigurationSelector源码
public class AsyncConfigurationSelector extends AdviceModeImportSelector<EnableAsync> {
private static final String ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME =
"org.springframework.scheduling.aspectj.AspectJAsyncConfiguration";
@Override
@Nullable
public String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
return new String[] {ProxyAsyncConfiguration.class.getName()};
case ASPECTJ:
return new String[] {ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME};
default:
return null;
}
}
}
Использовать по умолчаниюAdviceMode
заPROXY
, импортныйProxyAsyncConfiguration
Добрый.
@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyAsyncConfiguration extends AbstractAsyncConfiguration {
@Bean(name = TaskManagementConfigUtils.ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public AsyncAnnotationBeanPostProcessor asyncAdvisor() {
Assert.notNull(this.enableAsync, "@EnableAsync annotation metadata was not injected");
AsyncAnnotationBeanPostProcessor bpp = new AsyncAnnotationBeanPostProcessor();
Class<? extends Annotation> customAsyncAnnotation = this.enableAsync.getClass("annotation");
if (customAsyncAnnotation != AnnotationUtils.getDefaultValue(EnableAsync.class, "annotation")) {
bpp.setAsyncAnnotationType(customAsyncAnnotation);
}
if (this.executor != null) {
bpp.setExecutor(this.executor);
}
if (this.exceptionHandler != null) {
bpp.setExceptionHandler(this.exceptionHandler);
}
bpp.setProxyTargetClass(this.enableAsync.getBoolean("proxyTargetClass"));
bpp.setOrder(this.enableAsync.<Integer>getNumber("order"));
return bpp;
}
}
существуетProxyAsyncConfiguration
изasyncAdvisor
метод получения@EnableAsync
Некоторые настройки по значению, например:this.enableAsync.getBoolean("proxyTargetClass")
,this.enableAsync.<Integer>getNumber("order")
.
this.enableAsync
это его родительский классAbstractAsyncConfiguration
характеристики.AbstractAsyncConfiguration
ДостигнутоImportAware
интерфейс, так что вы можете получить@EnableAsync
информация о.
// AbstractAsyncConfiguration#setImportMetadata 源码
public void setImportMetadata(AnnotationMetadata importMetadata) {
this.enableAsync = AnnotationAttributes.fromMap(
importMetadata.getAnnotationAttributes(EnableAsync.class.getName(), false));
if (this.enableAsync == null) {
throw new IllegalArgumentException(
"@EnableAsync is not present on importing class " + importMetadata.getClassName());
}
}
Может быть, этот пример немного сложен, есть немного более простой пример:EnableRedisHttpSession
. В связи с этим читатели могут просмотреть исходный код для отладки и изучения.
Спасибо, что обратите внимание на общественное число WeChat: