1. Введение
мы вПредыдущийправильноMybatisкакMapperинтерфейсная инъекцияSpring IoCПосле анализа некоторые студенты спросили Толстого Брата, какая польза от этого, этот эффект на самом деле довольно большой, например, он позволяет добиться аналогичного@Controller
аннотаций (или наследовать единый интерфейс) для выполнения, таких как унифицированная инъекция запланированных задач илиWebsocketУнифицированная инъекция процессоров и т. д. будет иметь некоторые общиеBeanДинамический впрыск.
// 模仿 Controller
@XBean(description = "ETL JOB")
public class JobShedule {
@Caller(cron = "* * 0/5 * * ?")
public void exec(){
// job
}
}
Вышеупомянутый псевдокод представляет собой синхронизированный компонент задачи, который имитирует контроллер.
2. Идеи дизайна
Я обобщил подробные идеи разработки и дизайна, и вы можете реализовать эту функцию, если будете следовать инструкциям.
2.1 Определение аннотаций сканирования
определить что-то вроде@MappScan
импортировать настройкиImportBeanDefinitionRegistrar
и укажите диапазон сканируемых пакетов.
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Import(XBeanDefinitionRegistrar.class)
public @interface XBeanScan {
String[] basePackages();
}
Мы настроили аннотацию скана@XBeanScan
. Он имеет две функции:
- пройти через
basePackages
Задает область сканирования пакетов. - импортировать наш обычай
ImportBeanDefinitionRegistrar
реализацияXBeanDefinitionRegistrar
.
2.2 Определение общих тегов для целевых компонентов
Обычно мы можем выбрать интерфейс идентификации, и все его реализующие классы будут внедрены.Spring IoC; или с более удобной аннотацией все классы, помеченные этой аннотацией, будут инжектированыSpring IoC. Здесь мы используем более гибкие и удобные аннотации для реализации@XBean
Аннотация маркера:
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface XBean {
String description() default "";
}
2.3 Внедрение сканера
SpringФреймворк предоставляет нам сканеры для регистрации помеченныхBean, этопоследний разделУпомянулClassPathBeanDefinitionScanner
, мы наследуем его с небольшой модификацией:
public class XBeanDefinitionScanner extends ClassPathBeanDefinitionScanner {
public XBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
super(registry, useDefaultFilters);
super.addIncludeFilter(new AnnotationTypeFilter(XBean.class));
}
}
Здесь мы не используем фильтр по умолчанию, мы указываем, что цель, сканируемая сканером,@XBean
отмеченныеBean.
2.4 Реализация реестра компонентов
Главное событие здесь, нам нужно2.1прибыть2.3Эти компоненты определены вImportBeanDefinitionRegistrar
собирается в реализации.
/**
* The type X bean definition registrar.
*
* @author felord.cn
* @since 2020 /9/18 22:59
*/
public class XBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {
private ResourceLoader resourceLoader;
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 不使用默认过滤器
XBeanDefinitionScanner xBeanDefinitionScanner = new XBeanDefinitionScanner(registry, false);
xBeanDefinitionScanner.setResourceLoader(resourceLoader);
// 扫描XBeanScan注解指定的包
xBeanDefinitionScanner.scan(getBasePackagesToScan(importingClassMetadata));
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
/**
* 获取{@link XBeanScan}中声明的扫描包路径
* @param metadata the meta
* @return 包路径数组
*/
private String[] getBasePackagesToScan(AnnotationMetadata metadata) {
String name = XBeanScan.class.getName();
AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(name, true));
Assert.notNull(attributes, () -> "No auto-configuration attributes found. Is " + metadata.getClassName()
+ " annotated with " + ClassUtils.getShortName(name) + "?");
return attributes.getStringArray("basePackages");
}
}
из метаданных аннотацийimportingClassMetadata
Разбираем нужный нам путь сканированияbasePackages
Дождитесь метаданных, а затем позвольте сканеру просканировать этот путь.
2.5 Использование
С участием@Configuration
Класс помечен илиSpring BootизMain
использовать на уроке@XBeanScan
Вот и все, не так ли просто!
фактически
@ComponentScan
обеспечивает аналогичный функционал.
3. Резюме
Эта статья правильнаяПредыдущийКонкретное применение теории, честно говоря, последняя статья была скучной или даже не в состоянии уловить главное, но иногда теория такая. Как только вы прочитаете ее вместе с этой статьей, вы вдруг поймете. Если вам нужен более детальный контроль, добавьте этиBeanDefinitionRegistryPostProcessor
а такжеFactoryBean
ЖдатьSpringпредоставленный функциональный интерфейс. Что вам нужно узнать из этих двух статей, так это то, как использовать существующие компоненты для реализации собственной логики, читая исходный код по аналогии. Это большое улучшение для вас. Ну вот и все на сегодня, уделяйте больше внимания:Код Фермер Маленький Толстый БратВас ждут еще галантереи.
关注公众号:Felordcn获取更多资讯