Пройдено в предыдущей серии статей:
1.@EnableAspectJAutoProxyоткрытая параAspectJавтоматическая поддержка прокси,оригинальный клик:Базовая конфигурация Spring4.x (3): Spring AOP.
2.@EnableAsyncВключить поддержку асинхронных методов,оригинальный клик:Дополнительные темы Spring 4.x (2): многопоточность.
3.@EnableSchedulingВключите поддержку запланированных задач,оригинальный клик:Расширенные темы Spring 4.x (3): запланированные задачи.
В следующей серии статей SpringMvc будет задействовано использование другого @Enable* через:
1.@EnableWebMvcвключиWebMVCподдержка конфигурации.
2.@EnableConfigurationPropertiesоткрытая пара@ConfigurationPropertiesКонфигурация аннотацииBeanслужба поддержки.
3.@EnableJpaRepositoriesоткрытая параSpringDataJPARepositoryслужба поддержки.
4.@EnableTransactionManagementВключает поддержку аннотированных транзакций.
5.@EnableCachingВключить поддержку кэша аннотаций.
через простой@Enable*Чтобы открыть поддержку функции, чтобы избежать самостоятельной настройки большого количества кода, что значительно снижает сложность использования. Так каков же принцип реализации этой магической функции? Давайте изучим это.
@Configuration
public class SchedulingConfiguration {
@Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() {
return new ScheduledAnnotationBeanPostProcessor();
}
}
наблюдая за этими@Enable*В исходном коде аннотации обнаружено, что все аннотации имеют@Importаннотация,@ImportОн используется для импорта классов конфигурации, что означает, что эти автоматически включенные реализации фактически импортируют некоторые автоматически настроенные компоненты. Эти импортированные конфигурации в основном делятся на следующие три типа:
1. Первая категория: напрямую импортировать класс конфигурации
@Target({java.lang.annotation.ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import({SchedulingConfiguration.class})
@Documented
public @interface EnableScheduling
{
}
можно увидетьEnableSchedulingПРИМЕЧАНИЕ Прямой класс конфигурации импортаSchedulingConfiguration, этот класс аннотируется@Configurationи зарегистрировалscheduledAnnotationProcessorБин,SchedulingConfigurationИсходный код выглядит следующим образом:
@Configuration
public class SchedulingConfiguration {
@Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() {
return new ScheduledAnnotationBeanPostProcessor();
}
}
2. Вторая категория: выберите категорию конфигурации в соответствии с условиями
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AsyncConfigurationSelector.class)
public @interface EnableAsync {
Class<? extends Annotation> annotation() default Annotation.class;
boolean proxyTargetClass() default false;
AdviceMode mode() default AdviceMode.PROXY;
int order() default Ordered.LOWEST_PRECEDENCE;
}
AsyncConfigurationSelectortВыберите класс конфигурации, который необходимо импортировать по условию.AsyncConfigurationSelectorКорневой интерфейсImportSelector, этот интерфейс нужно переписатьselectImportsметод, при котором выносится предварительное суждение. В этом примере, еслиadviceModeдляPROXY, затем вернутьсяProxyAsyncConfigurationЭтот класс конфигурации; еслиadviceModeдляASPECTJ, затем вернутьсяAspectJAsyncConfigurationКласс конфигурации, исходный код выглядит следующим образом:
public class AsyncConfigurationSelector extends AdviceModeImportSelector<EnableAsync> {
private static final String ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME =
"org.springframework.scheduling.aspectj.AspectJAsyncConfiguration";
/**
* {@inheritDoc}
* @return {@link ProxyAsyncConfiguration} or {@code AspectJAsyncConfiguration} for
* {@code PROXY} and {@code ASPECTJ} values of {@link EnableAsync#mode()}, respectively
*/
@Override
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;
}
}
}
3. Третья категория: динамическая регистрация бинов
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
/**
* Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
* to standard Java interface-based proxies. The default is {@code false}.
*/
boolean proxyTargetClass() default false;
}
AspectJAutoProxyRegistrarДостигнутоImportBeanDefinitionRegistrarинтерфейс,ImportBeanDefinitionRegistrarФункция состоит в том, чтобы автоматически добавлять bean-компоненты в существующие классы конфигурации во время выполнения, переопределяя метод:
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)
в,AnnotationMetadataПараметр используется для получения аннотации к текущему классу конфигурации,BeanDefinitionRegistry Параметры используются для регистрации бинов. Исходный код выглядит следующим образом:
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
/**
* Register, escalate, and configure the AspectJ auto proxy creator based on the value
* of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
* {@code @Configuration} class.
*/
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
}
} награда Добро пожаловать в публичный аккаунт Life Designer в WeChat.Публичный идентификатор: longjiazuoA