路由装饰器
@controller 装饰器标注了控制器,装饰器有一个可选参数,用于进行路由前缀,这样控制器下面的所有路由都会带上这个前缀。
import { Controller, Get } from '@midwayjs/decorator'; @Controller('/test') export class HomeController { @Get('/') async home(): Promise<string> { return 'Hello Midwayjs!'; } }
在浏览器中输入127.0.0.1:7001 报错
报错信息告诉我们路由找不到,那么我们改一下浏览器中的路由127.0.0.1:7001/test,我们得到了我们想要的结果,这里我们可以知道装饰器中的参数匹配我们的路由
HTTP装饰器
我们改写一下代码
import { Controller, Get, Post } from '@midwayjs/decorator'; @Controller('/test') export class HomeController { @Post('/') async home(): Promise<string> { return 'Hello Midwayjs!'; } }
通过使用Postman 调用接口,将请求方式改为post,可以看到我们拿到我们请求的接口了。
依赖注入
依赖注入(DI)、控制反转(IoC)等是Spring的核心思想,那么在midwayjs中通过装饰器的轻量特性,让依赖注入变得非常优雅。@Provide 的作用是告诉 依赖注入容器 ,我需要被容器所加载。@Inject 装饰器告诉容器,我需要将某个实例注入到属性上。下面例子🌰中,实现了一个UserService并通过**@Provide注入到容器中,在app.controller中,我们通过@Inject** 拿到了userService的实例。
// service.ts import { Provide } from '@midwayjs/decorator'; import { IUserOptions } from '../interface'; @Provide() export class UserService { async getUser(options: IUserOptions) { return { uid: options.uid, username: 'mockedName', phone: '12345678901', email: 'xxx.xxx@xxx.com', }; } }
// hello.ts import { Inject, Controller, Get, Query } from '@midwayjs/decorator'; import { Context } from '@midwayjs/koa'; import { UserService } from './service'; @Controller('/api') export class APIController { @Inject() ctx: Context; @Inject() userService: UserService; @Get('/get_user') async getUser(@Query('uid') uid) { const user = await this.userService.getUser({ uid }); return { success: true, message: 'OK', data: user }; } }
那么我们请求一下接口:
依赖注入原理
我们以下面的伪代码举例,在 Midway 体系启动阶段,会创建一个依赖注入容器(MidwayContainer),扫描所有用户代码(src)中的文件,将拥有 @Provide 装饰器的 Class,保存到容器中。
/***** 下面为 Midway 内部代码 *****/ const container = new MidwayContainer(); container.bind(UserController); container.bind(UserService);
这里的依赖注入容器类似于一个 Map。Map 的 key 是类对应的标识符(比如 类名的驼峰形式字符串),Value 则是 类本身。
在请求时,会动态实例化这些 Class,并且处理属性的赋值,比如下面的伪代码,很容易理解。
/***** 下面为依赖注入容器伪代码 *****/ const userService = new UserService(); const userController = new UserController(); userController.userService = userService;
经过这样,我们就能拿到完整的 userController 对象了,实际的代码会稍微不一样。
MidwayContainer 有 getAsync 方法,用来异步处理对象的初始化(很多依赖都是有异步初始化的需求),自动属性赋值,缓存,返回对象,将上面的流程合为同一个。
/***** 下面为依赖注入容器内部代码 *****/ // 自动 new UserService(); // 自动 new UserController(); // 自动赋值 userController.userService = await container.getAsync(UserService); const userController = await container.getAsync(UserController); await userController.handler(); // output 'world'
以上就是依赖注入的核心过程,创建实例。





