IOC,把控制反轉到業務端,這句話沒什麼問題,在springboot框架裏,對象的管理是經過spring ioc來實現的,而開發人員的開發原則里老是說「面向接口編程」,而爲何要面向接口卻沒幾我的能說出來,今天在寫一個基於redis的手動分佈鎖時,對這個面向接口和控制反轉又有了一個體會。redis
當你爲開發人員提供一個封閉的包時,他們是直接用的,他們不會修改你的代碼,固然他們能夠去繼承並擴展;固然若是你不但願被繼承能夠聲明爲final
,這都是面向對象編程裏提供好的功能,咱們主要看控制反轉
這句話,它把控制權交給了上層去實現,底層經過 面向接口
的原則只設計一個規範,而又使用者去實現;但框架功能裏的細節是要有的,這相似於「模版方法」模式,底層框架實現了流程,而個性化的部分由上層去實現。算法
public interface AuditorAware<T> { /** * Returns the current auditor of the application. * * @return the current auditor */ Optional<T> getCurrentAuditor(); }
上面這個泛型接口只有一個方法,須要讓上層開發人員根據本身的業務去實現它,比較返回一個當前登錄的用戶實體,或者返回用戶名稱,而後底層框架裏直接使用這個AuditorAware接口的對象;固然若是你的底層只接收一個String類型的值,你也能夠去派生一個個性化接口,讓上層開發人員去實現你的接口便可。spring
/** * 返回用戶ID的標識接口,由程序使用者去實現. */ public interface UserIdAuditorAware extends AuditorAware<String> { }
上面代碼更加準確的規定了AuditorAware是一個字符串的接口,只返回用戶ID便可。編程
@Component public class CurrentUserAware implements UserIdAuditorAware { @Autowired ApplicationContext applicationContext; @Override public Optional<String> getCurrentAuditor() { ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = requestAttributes.getRequest(); return Optional.of(request.getSession().getAttribute("id").toString()); } }
咱們的底層代碼會使用它的getCurrentAuditor()
返回值 ,它是一個字符串。設計模式
public Object execute(String sourceId, Integer timeout, TimeUnit unit) { Assert.notNull(sourceId, "sourceId不能爲空"); String key = getKey(sourceId); String user = auditorAware.getCurrentAuditor().orElse(null); Assert.notNull(user, "AuditorAware實例返回的值爲空"); // 代碼略 }
對於一個小小的功能,咱們在通過思考以後,對於以前學過的東西進行總結,你可能會想法某種設計模式、某個算法、某個原則、在使用它們以後,讓你的代碼擴展性更好,這種代碼也彷彿有了生命!springboot