javascript
Spring Boot 2 实践记录之 条件装配
實(shí)驗(yàn)項(xiàng)目是想要使用多種數(shù)據(jù)庫訪問方式,比如 JPA 和 MyBatis。
項(xiàng)目的 Service 層業(yè)務(wù)邏輯相同,只是具體實(shí)現(xiàn)代碼不同,自然是一組接口,兩組實(shí)現(xiàn)類的架構(gòu)比較合理。
不過這種模式卻有一個問題,如果 Bean 是按實(shí)現(xiàn)類裝配,則在切換數(shù)據(jù)庫訪問方式時(shí),就需要大量的代碼修改。如果按接口裝配,則會出現(xiàn)歧義(同一接口有兩個實(shí)現(xiàn),無法自動裝配)。
雖然可以使用「首選Bean」或「限定」裝配,但是與直接使用實(shí)現(xiàn)類裝配一樣,切換數(shù)據(jù)庫訪問地,仍然要大量修改源碼。
經(jīng)過實(shí)驗(yàn),使用「條件裝配」實(shí)現(xiàn)了利用配置切換數(shù)據(jù)庫訪問方式,不需要修改代碼了。
示例:
先定義 Service 接口:
public interface UserServiceInterface {...... }再定義 MyBatis 實(shí)現(xiàn)類:
@Service @Conditional(MybatisCondition.class) public class UserServiceMybatisImpl implements UserServiceInterface {...... }注意其中的 @Conditional(MybatisCondition.class),MybatisCondition 類必須實(shí)現(xiàn) org.springframework.context.annotation.Condition 接口,該接口僅有一個 matches 方法,當(dāng)該方法返回真時(shí),UserServiceMybatisImpl 被裝配。
MybatisCondition 的 matches 方法的邏輯被實(shí)現(xiàn)為根據(jù)配置文件中的 use.data.access.method 屬性是否為 mybatis,來決定是否裝配?UserServiceMybatisImpl 類:
import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.env.Environment; import org.springframework.core.type.AnnotatedTypeMetadata;public class MybatisCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {Environment env = context.getEnvironment();if (env.getProperty("use.data.access.method").equals("mybatis")) {return true;}return false;} }再定義 SPA 實(shí)現(xiàn)類及其 SpaCondition 類,實(shí)現(xiàn)方式與 Mybatis 相同,僅在配置項(xiàng)為 spa 時(shí),裝配 UserServiceSpaImpl 類:
@Service @Conditional(SpaCondition.class) public class UserServiceSpaImpl implements UserServiceInterface {...... } import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.env.Environment; import org.springframework.core.type.AnnotatedTypeMetadata;public class SpaCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {Environment env = context.getEnvironment();if (env.getProperty("use.data.access.method").equals("spa")) {return true;}return false;} }定義一個類,自動裝配 UserServiceInterface,并打印其類名:
public class Test {@Autowiredprivate UserServiceInterface userServiceInterface;public void testUserService() {System.out.println(userServiceInterface.getClass();} }現(xiàn)在還不能運(yùn)行,需要添加配置項(xiàng)。
先將配置項(xiàng)配置為 mybatis:
use.data.access.method = mybatis運(yùn)行 Test 類的 testUserService 方法,結(jié)果為:
UserServiceMybatisImpl將配置項(xiàng)修改為 spa:
use.data.access.method = spa運(yùn)行 Test 類的 testUserService 方法,結(jié)果為:
UserServiceSpaImpl?
不過,有個小小的缺憾,就是在 Idea 中,如下代碼行:
@Autowired private UserServiceInterface userServiceInterface;會有錯誤提示:
Could not autowire. There is more than one bean of 'UserServiceInterface' type. Beans: userServiceMybatisImpl?? (UserServiceMybatisImpl.java)userServiceSpaImpl?? (UserServiceSpaImpl.java)
由于配置項(xiàng)是在運(yùn)行時(shí)讀取的,Idea 在靜態(tài)語法檢查時(shí),實(shí)在沒辦法搞定這個自動裝配的判斷。
沒關(guān)系,不影響運(yùn)行!
轉(zhuǎn)載于:https://www.cnblogs.com/matchless/p/10389918.html
總結(jié)
以上是生活随笔為你收集整理的Spring Boot 2 实践记录之 条件装配的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Prolog学习笔记100805
- 下一篇: Spring - shortcuts