【发布时间】:2020-09-10 06:24:03
【问题描述】:
我正在尝试为Spring框架编写自己的@Enable注解,应该使用如下:
package com.example.package.app;
@SpringBootApplication
@com.example.annotations.EnableCustom("com.example.package.custom")
public class MyApplication {}
我关注了Component scan using custom annotation,但这带来了一些限制:
-
我无法使基础包属性动态化,即无法传递
"com.example.package.base",但需要在配置时预先定义包。我查看了
@AliasFor,但无法正常工作。 -
当我省略基本包时,扫描从注释的定义包开始,而不是从注释类的包开始。在上面的示例中,它只会扫描和创建
com.example.annotations中的类的 bean,而不是com.example.package.*。我查看了
EntityScanPackages.Registrar.class,它是在@EntityScan注释中导入的,但它是一个内部类,我的注释无法导入。
如果我将@ComponentScan(includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, value = MyAnnotation.class)) 放在MyApplication 类上,一切正常,但当它移到@EnableCustom 的元注释时停止工作。如何告诉 Spring Framework 将 @EnableCustom 视为使用一些默认值指定 @ComponentScan 的不同方式。我尝试使用 @Configuration、@Component 和其他人对我的注释进行元注释,但无济于事:
@Configuration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@ComponentScan(
includeFilters = @ComponentScan.Filter(
type = FilterType.ANNOTATION,
value = ApplicationService.class))
public @interface EnableApplicationServices {
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] value() default {};
}
我在哪里可以找到这方面的文档,或者您会推荐什么起点?我的长期目标是拥有一个可供众多项目使用的 Spring Boot 启动器。
可以在以下存储库中找到一个 M(N)WE:https://github.com/knittl/stackoverflow/tree/spring-enable-annotation
以下是包结构的概要:
// com.example.annotations.EnableCustom.java
@Configuration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
// this annotation is never honored:
@ComponentScan(
includeFilters = @ComponentScan.Filter(
type = FilterType.ANNOTATION,
value = MyAnnotation.class))
//@Import(EnableCustom.EnableCustomConfiguration.class)
public @interface EnableCustom {
// this annotation works in combination with @Import, but scans the wrong packages.
@ComponentScan(
includeFilters = @ComponentScan.Filter(
type = FilterType.ANNOTATION,
value = MyAnnotation.class))
class EnableCustomConfiguration {}
}
// file:com.example.app.Application.java
@SpringBootApplication
@EnableCustom("com.example.app.custom.services")
// @ComponentScan(
// includeFilters = @ComponentScan.Filter(
// type = FilterType.ANNOTATION,
// value = MyAnnotation.class)) // <- this would work, but I want to move it to a custom annotation
public class Application {
}
// file:com.example.app.custom.services.MyService
@MyAnnotation
public class MyService {
public MyService() {
System.out.println("Look, I'm a bean now!");
}
}
// file:com.example.annotations.services.WrongService.java
@MyAnnotation
public class WrongService {
public WrongService() {
System.out.println("I'm in the wrong package, I must not be instantiated");
}
}
【问题讨论】:
-
如果我是对的,你想制作自己的@ComponentScan 注释吗?
-
@AnishB。是的,这基本上就是我想要做的。我想创建一个自定义注释,它可以使用预定义的设置进行组件扫描(即为具有另一个自定义注释的类创建 bean),但足够灵活,以便注释的用户仍然可以配置基本包。如果自定义注释不是解决此问题的正确方法,但存在另一种解决方案,那也没关系。但看起来大多数其他库或框架都依赖于某种
@Enable…注释。 -
嗨,我已经在 myannotation 上注册了组件,它可以与普通组件一起使用。在 EnableCustom 上工作是否需要过滤器。
标签: java spring spring-annotations component-scan spring-autoconfiguration