在Spring中经常会碰到这样的问题,在service中经常需要注入第三方的配置信息,如:搜索引擎,消息队列等....但是由于service作为各个C端的中间的桥接层,所以需要在没额C端都配置上对应的配置文件或者实体声明,可能在这些C端中,根本就没有用到相关的功能!...如何能优雅的去除掉不需要的依赖?
本人总结了一下两个方法,不足的地方还忘大家指点:
1:将第三方依赖项单独做成一个service-jar包,在需要的项目中进行引用即可,但是前提,本身的项目结构的依赖,解耦有较好的规划
2:在不需要用到该功能的C端,进行注入对象的过滤.
这里就第二点进行简单的描述:
因spring中对象的注入,我们一般使用的是ioc的方式,使用注解@Autowired注解需要注入的对象,但是再某些C端,可能根本没用带改对象,也就自然没有该对象的注入,这时候,启动项目,你会发现报错,找不到该注入对象.spring报错信息还是挺准确的.对,我们受限想到的就是忽略该对象,查看@Autowired,源码如下:
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Autowired { /** * Declares whether the annotated dependency is required. * <p>Defaults to {@code true}. */ boolean required() default true; }
required,是否必须.我们设为false,即可,如下:
@Autowired(required=false) private MQConfig config; //引用统一的参数配置类
这是直接忽略掉该注入对象,还有种情况,我们需要忽略掉掉整个实现类中的对象注入这么办呢?或者忽略掉整个类的声明这么办呢?
spring-context提供了多种支持
摘自其他网站的介绍:
context:component-scan节点允许有两个子节点<context:include-filter>和<context:exclude-filter>。filter标签的type和表达式说明如下:
Filter Type | Examples Expression | Description |
annotation | org.example.SomeAnnotation | 符合SomeAnnoation的target class |
assignable | org.example.SomeClass | 指定class或interface的全名 |
aspectj | org.example..*Service+ | AspectJ語法 |
regex | org\.example\.Default.* | Regelar Expression |
custom | org.example.MyTypeFilter | Spring3新增自訂Type,實作org.springframework.core.type.TypeFilter |
在我们的示例中,将filter的type设置成了正则表达式,regex,注意在正则里面.表示所有字符,而\.才表示真正的.字符。我们的正则表示以Dao或者Service结束的类。
本人项目中的一个简单配置实例spring-context.xml如下:
<context:component-scan base-package="com.xyy"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/> <context:exclude-filter type="aspectj" expression="com.xyy.driver..*"/> <context:exclude-filter type="aspectj" expression="com.xyy.erp..*"/> <context:exclude-filter type="assignable" expression="com.xyy.common.config.ESMQConfig"/> <context:exclude-filter type="assignable" expression="com.xyy.common.config.MQConfig"/> </context:component-scan>
因为上面非必需注入对象
MQConfig种还包含了其他属性的注入,所以这里直接再spring的包扫描中忽略该对象的声明...