站在架構(gòu)的角度,很多思想都是相通的爱只,跟你用什么語言無關(guān),做什么平臺無關(guān)招刹,也不管你是前端還是后端恬试。
最開始接觸mvvm是在RN項目中,接著做小程序也是mvvm疯暑,后面flutter亦是如此训柴,Android原生的livedata也跟上了。
響應(yīng)式編程出現(xiàn)后妇拯,各種語言版本的Rx都出來了幻馁,Rxjava,Rxjs乖阵,Rxdart宣赔,Rxswift,Rxpy瞪浸,Rxgo等等。
再看看分布式概念吏祸,Android這邊的組件化插件化何其相似对蒲,讓每個業(yè)務(wù)可以單獨運行調(diào)試钩蚊。服務(wù)端的微服務(wù),每個服務(wù)相互隔離互不影響?yīng)毩㈤_發(fā)蹈矮。華為的鴻蒙系統(tǒng)都是分布式系統(tǒng)砰逻。
最近這段時間學(xué)習(xí)了下java服務(wù)端,很多技術(shù)思想也都是相同的泛鸟。
Spring框架
spring是一種mvc模式開發(fā)蝠咆,主要分為3層,controller+service+dao層北滥。
@Controller
@Api(tags = "UmsMemberController", description = "會員登錄注冊管理")
@RequestMapping("/sso")
public class UmsMemberController {
@Value("${jwt.tokenHeader}")
private String tokenHeader;
@Value("${jwt.tokenHead}")
private String tokenHead;
@Autowired
private UmsMemberService memberService;
@ApiOperation("會員登錄")
@RequestMapping(value = "/login", method = RequestMethod.POST)
@ResponseBody
public CommonResult login(@RequestParam String username,
@RequestParam String password) {
String token = memberService.login(username, password);
if (token == null) {
return CommonResult.validateFailed("用戶名或密碼錯誤");
}
Map<String, String> tokenMap = new HashMap<>();
tokenMap.put("token", token);
tokenMap.put("tokenHead", tokenHead);
return CommonResult.success(tokenMap);
}
}
@Service
public class UmsMemberServiceImpl implements UmsMemberService {
@Override
public String login(String username, String password) {
String token = null;
try {
UserDetails userDetails = loadUserByUsername(username);
if(!passwordEncoder.matches(password,userDetails.getPassword())){
throw new BadCredentialsException("密碼不正確");
}
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
token = jwtTokenUtil.generateToken(userDetails);
} catch (AuthenticationException e) {
LOGGER.warn("登錄異常:{}", e.getMessage());
}
return token;
}
}
從上面代碼可以看到刚操,在controller中,我們并沒有去new 一個service出來再芋,但是卻可以直接使用菊霜,肯定是和上面的注解autowired有關(guān)系。spring中主要運用到了IOC济赎,DI鉴逞,AOP思想,IOC和DI其實是不同層面上的同一個意思司训。
先來看看概念:
IOC(Inversion of Control构捡,控制反轉(zhuǎn))意思:是控件反轉(zhuǎn)也就是由容器控制程序之間的關(guān)系,把控件權(quán)交給了外部容器壳猜,從程序代碼直接操控叭喜,到控制權(quán)交給外部容器管理,控制權(quán)的轉(zhuǎn)移是所謂反轉(zhuǎn)
IOC的三種注入方式:
接口注入:如果采用接口注入一個Bean蓖谢,那么通過注入的Bean就必須要實現(xiàn)這個接口(這很霸道對不對捂蕴,我想實現(xiàn)什么接口,還需要規(guī)定)...
set方法注入:如果采用set注入一個Bean闪幽,那么只需要為Bean中所需要的一些組件提供set方法就可以啥辨,通過set方法注入比較清晰,大家一看就知道(哦~原來你想這個Bean提供了這些組件)...
構(gòu)造器注入:如果采用構(gòu)造器注入方式盯腌,那么首先為這個Bean提供自定義的構(gòu)造函數(shù)溉知,構(gòu)造函數(shù)中需要的參數(shù)就是類中的組件實例。
Spring DI
DI的意思:DI(Dependency Injection腕够,依賴注入) 側(cè)重于過程级乍, 把對象通過setter、contruct帚湘、args等方式 注入到另一個對象中作為這個對象的一個成員變量
Spring Aop
AOP為(Aspect Oriented Programming玫荣,面向切面編程):AOP可以對業(yè)務(wù)邏輯 的各個部分進行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低大诸,提高程序的可重用性捅厂,同時提高 了開發(fā)的效率贯卦。
AOP
Aspect(切面):通常是一個類,里面可以定義切入點和通知
JointPoint(連接點):程序執(zhí)行過程中明確的點焙贷,一般是方法的調(diào)用
Advice(通知):AOP在特定的切入點上執(zhí)行的增強處理撵割,有 before,after,afterReturning,afterThrowing,around
Pointcut(切入點):就是帶有通知的連接點,在程序中主要體現(xiàn)為書寫切入點表達(dá)式
AOP代理:AOP框架創(chuàng)建的對象辙芍,代理就是目標(biāo)對象的加強啡彬。Spring中的AOP代理可以使JDK動態(tài)代理,也可以是CGLIB代理故硅,前者基于接口庶灿,后者基于子類。
作為一個Android開發(fā)者契吉,可以捕捉到一些熟悉的關(guān)鍵詞跳仿,用過dagger2或者butterknife的時候肯定是見過控制反轉(zhuǎn)和依賴注入這幾個詞的。用過retrofit的人肯定是知道動態(tài)代理的捐晶。 在Anroid中的AOP切面主要是用到的AspectJ菲语,不侵入式的修改代碼。
在dagger2/butterknife中很容易看到類似Spring的這種代碼風(fēng)格
public class MainActivity extends AppCompatActivity {
@Inject
ApiServer mApiServer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mApiServer.register();
}
}
public class ApiServer {
@Inject
public ApiServer(){
Log.e("Howard","ApiServer--->start");
}
public void register() {
Log.e("Howard","ApiServer--->register");
}
}
class ExampleActivity extends Activity {
@BindView(R2.id.user) EditText username;
@BindView(R2.id.pass) EditText password;
...
}
原理基本都差不多惑灵,現(xiàn)在框架為了解耦山上,基本上就是 注解、反射英支、動態(tài)代理佩憾、javapoet這一套了。我們可以從大部分的框架中看到他們的身影,除了butterknife,dagger2這兩個典型干花,還有諸如 retrofit,eventbus,arouter,wmrouter等等等妄帘。