Java研究院 Java研究院

人非生而知之者,知之,而后知不知。

目录
Spring扫描组件完成自定注入的问题(续)
/    

Spring扫描组件完成自定注入的问题(续)

昨天给小老弟讲了下Spring组件注入过滤的问题,但是小老弟好像没完全开窍,还提了新的要求。他想在老项目中将原有的各种加了@Service注解的类排除在注入之外,然后自己重新写一批Service,美其名曰“不破坏~”

呵呵,天真的小老弟!

不过话说回来,想到这个命题的时候感觉也不难。Spring既然能允许我们自定义设置过滤规则,那肯定是可以实现这种自定义的。姑且按照不破坏的原则吧,也可以有很多种方式来实现,我们先来看个例子。

image.png

这里我在两个包下定义了 StudentService ,为了方便查看对比,在Service注解指定了不同的value。然后我们启动项目,查看Spring 注入了哪些 Bean ,结果会看到两个 StudentService 都注入了。

image.png

假设我们原有的逻辑都在注明为 aNewService 的 StudentService中,那么我们应该在项目启动后看不到aNewService 了,如何实现?

结合之前的文章,其实无非就是将 service 包下的 StudentService 过滤嘛!

但实际情况可能会比这个复杂,比如我们的 Service 可能分在在不同的包下,又或者可能只是想排除其中的某几个或者某些子包下的 Service。

小老弟想简单粗暴的通过排除 @Service 注解来实现,其实也不是不可以,但是问题在于有很多不是我们自定义的 Service可能也用了这个注解,比如一些三方插件等等,这种方式很容易引发一些莫名其妙的问题。

还有一点就是,@ComponentScan 里 excludeFilters 的优先级比 includeFilters 的优先级要高,那也就意味着你排除容易,想加进来就难了。

如果想优雅一点,可以采用自定义注解的方式来实现。比如这样:

@ComponentScan(useDefaultFilters = false,
		excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = CustomerFilterType.class)}
)

这样的话,在需要排除的类上加上 CustomerFilterType 注解就可以实现了。好处是灵活多变,对代码的侵入其实也很少。坏处嘛,就是如果类太多的话,工程量也不小。

自定义注解过滤

如果不想用自定义注解,那就可以通过自定义的方式,比如前文提到的 StudyingFilter 方式,里面的match方法不仅匹配了包路径,还能匹配类名。这种方式相比注解方式来说,可以更为细粒度的控制哪些类是需要排除的。

比如这样:

@ComponentScan(useDefaultFilters = true,
		excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = CustomerFilterType.class),
				@ComponentScan.Filter(type = FilterType.CUSTOM, classes = StudyingFilter.class)}
)

我这边重新定义了service3包下的StudentService,并在自定义过滤器中将该包下的所有类过滤掉,采用了组合排除的方式,可以看到只有aOldService被注入了,效果如下:

组合过滤

Are u understand ?


才疏学浅,难免有坑,有坑也不填
标题:Spring扫描组件完成自定注入的问题(续)
地址:https://studying.icu/articles/2021/10/09/1633749472082.html