ARouter近期迎来了第一次大版本更新,完整提供了依赖注入、依赖查找两种控制反转(IOC)思想的实现,支持对Intent参数与自定义服务的自动装配
如果还没有了解过ARouter,可以参考上一篇:[Alibaba-ARouter] 简单好用的Android页面路由框架
前言
如果接触过服务端开发,肯定用到Spring这个框架,而Spring框架提供的能力中较为常见的就是控制反转(DI)与面向切面编程(AOP)的支持,这两种思想的引入,大大减轻了开发工作量,给程序员带来了便利的同时,也解决了业务代码与逻辑的耦合等问题。而这两种思想在移动端也有较多的运用,比方说Dagger2框架,就是一款较为常用的依赖注入框架
先说说控制反转
控制反转是一种思想,而依赖注入和依赖查找则是针对这种思想的实践,依赖注入机制降低了组件之间的依赖关系,同时也大大提高了组件的可复用性,在ARouter的应用中,把本来由用户控制的参数与服务的赋值,移交给了框架,对参数与服务赋值的控制进行了反转,从而解决了业务代码直接依赖服务实现的问题,如果没有这方面知识的积累,仅仅通过文字解释比较晦涩,请看下面部分的代码(通过控制反转的思想对业务代码进行解耦)
// 这部分是没有经过控制反转的逻辑
import xxxxxxx // 依赖了N多个乱七八糟的库
import xxxxxxx
public class Hello {
public static void sayHello() {
// ... 执行了100行各种业务逻辑
}
}
public class Business {
public static void main(String[]args) {
Hello hello = new Hello();
// 这里的hello实例是由用户new的,所以控制权还在用户手中,
// 但是用户需要自己去new各种各样的功能组件,需要用户自己
// 来管理hello的生命周期,这时就带来了单例、销毁等,各种问题
hello.sayHello();
}
}
我们稍稍对过程进行改写,完成Hello中复杂的业务实现与Business类的解耦(通过依赖查找)
public interface HelloService extends IProvider {
void sayHello();
}
@Route(path = "/service/hello")
public class Hello implements HelloService {
public static void sayHello() {
// ... 执行了100行各种业务逻辑
}
}
public class Business {
public static void main(String[]args) {
HelloService hello = ARouter.getInstance().navigation(HelloService.class);
// 这种情况下,就实现了Business和Hello的解耦,通过接口来调用,由ARouter来连接接口与实现,hello实例原本由用户来控制创建,变成了ARouter来管理,实现了控制的反转,这种控制反转的实践就是 依赖查找,虽然由框架来创建,但是还是用户来找到这个类的实例,在1.0.4版本中已经支持这种用法
hello.sayHello();
}
}
下面我们看看最新版本中ARouter对控制反转的支持(通过依赖注入)
// 和之前唯一的不同,就是在使用上的区别,这时候我们仅仅修改Buiness类即可
public class Business {
@Autowired
HelloService helloService;
public static void main(String[]args) {
ARouter.getInstance().inject(this); // 用来关联框架与this,可以通过基类的其他形式
// 这种情况下,在用户面来看,就是控制反转的另一种实现,
// 依赖注入,用户只需要声明该字段,并使用注解标注,在
// 运行期间,ARouter会自动给该字段赋值,用户不需要去给
// 该字段赋值,也不需要去查找该字段的值,直接使用即可,
// HelloService的具体实现类会在运行期由ARouter框架来指
// 定并赋值,是不是变得更简单更方便了
hello.sayHello();
}
}
新版本更新
ARouter日前发布了1.0.5版本,在原有的路由功能基础上,完善了对Intent参数与自定义服务的自动装配,目前通过URL直接导航到具体Native页面之后,URL中带有参数可以自动注入到目标页面的对应字段中,自定义Service同样支持,一般情况下,使用自定义服务的时候,只需要声明该字段,并使用 @Autowired注解标注,即可直接使用该字段,解放双手
// 目前支持的几种标注方式
// 1. 自定义服务
@Autowired
HelloService helloService; // 标准的标注,默认进行byType服务查找
@Autowired(required = true)
HelloService helloService; // 指定required为true之后,运行中该值获取不到的时候会触发Crash,方便开发中调试
@Autowired(name = "/service/hello")
HelloService helloService; // 指定name的sevice,会按照byName的方式进行服务查找,适用于同一个接口有多种实现的情况
// 2. intent 字段
// https://m.aliyun.com/test/activity1?name=老王&age=23&boy=true&high=180
// 对应参数的值会自动注入到对应属性之中,无需getIntent().getXxxx(),支持Fragment中使用
@Autowired
String name;
@Autowired
int age;
@Autowired(name = "boy")
boolean girl;
private long high;
@Autowired
String url;
后记
技术选型,比较重要的就是是否足够稳定、健壮、长期有人维护,目前ARouter提供了针对页面路由,App组件化,依赖注入等相关功能的一站式解决方案,一个SDK解决以上诸多问题,欢迎选用。
ARouter Github地址,欢迎Star与MR,大家共建