使用TypeScript装饰器简单模仿SpringBoot提供的@Configuration注解与@ConfigurationProperties注解

本文介绍了如何使用TypeScript模拟SpringBoot的@Configuration和@ConfigurationProperties注解,包括组件注册、配置绑定等功能。通过示例代码详细阐述了在TypeScript中创建容器、注册组件、查找组件以及绑定配置文件的过程,加深了对SpringBoot框架理解。
摘要由CSDN通过智能技术生成

这两天才开始学习SpringBoot,遇到了两个很有意思的注解,打算用TypeScript模拟一下

示例

配置文件

name: UpYou
map: {
    name: UpYou,
    age: 18
}
@ConfigurationProperties({ prefix: 'map' })
@Configuration
class Preson {
    public age?: number = undefined;

    public name?: string = undefined;

    constructor() {}
}

// 获取组件
const component = getComponentInIOC(Preson);

输出:Preson { age: 18, name: 'UpYou' }

@Configuration

这个注解是用来注册组件的,在SpringBoot也是比较重量级的东西了,ts中如何使用以及书写装饰器我就不多说了,网上有很多案例与教程

这是一个容器,所有注册的组件都在这

interface IOCMapType {
    [index: string]: any;
}
// IOC容器
const IOCMap: IOCMapType = {};

Configuration方法

function Configuration(target: Class) {
    const name = target.name;
    const inIOC = findComponentInIOCByName(name);
    if (!inIOC) {
        throw new Error('the component exists in container.');
    }
    addComponentToCantainer(target);
}

findComponentInIOCByName方法

这个方法主要查找容器中是否存在某个主键

// 在容器中通过组件名查找组件
function findComponentInIOCByName(name: string) {
    return IOCMap[name] === void 0;
}

addComponentToCantainer方法

这个主要用来注册组件到容器

// 将组件注册到容器
function addComponentToCantainer(component: Class) {
    IOCMap[component.name] = new component();
}

现在这个修饰器就写好了

@ConfigurationProperties

这个注解是用来绑定配置的
例如在某个规定位置下有一个application.yml文件,这是一个配置文件,那么通过这个注解可以将配置文件中对应的配置映射到被标注的类中。

例如我们在某个位置有一个application.yml文件

name: UpYou
map: {
    name: UpYou,
    age: 18
}

我们需要使用js-yaml插件来读取它

// 获取配置文件
const yml = fs.readFileSync('application.yml');
const config: any = yaml.load(yml.toString());

读取出来就是JSON格式
{ name: 'UpYou', map: { name: 'UpYou', age: 18 } }

ConfigurationProperties方法

type ConfigurationPropertiesParam = {
    prefix: string;
};
// 绑定配置文件
function ConfigurationProperties(args: ConfigurationPropertiesParam) {
    const nodes = args.prefix.split('.');
    return function (target: Class) {
        const component = getComponentInIOC(target.name);
        let conf = config;
        // 过滤配置文件
        for (const node of nodes) {
            if (conf[node] === void 0) {
                break;
            }
            conf = conf[node]
        }
        // 绑定配置文件对应值
        for (const field in conf) {
            if (Object.prototype.hasOwnProperty.call(component, field)) {
                if (component[field] instanceof Function) {
                    break;
                }
                component[field] = conf[field];
            }
        }
    };
}

这个循环主要将对应的配置文件过滤出来,例如prefixmap.test,需要拿的就是配置文件中map里边的test,通过.分割prefix的内容,然后一层一层循环进去就能拿到对应配置了。

const nodes = args.prefix.split('.');
for (const node of nodes) {
    if (conf[node] === void 0) {
        break;
    }
    conf = conf[node]
}

直接设置组件的字段就可以了。

// 绑定配置文件对应值
for (const field in conf) {
    if (Object.prototype.hasOwnProperty.call(component, field)) {
        if (component[field] instanceof Function) {
            break;
        }
        component[field] = conf[field];
    }
}

getComponentInIOC方法

这个方法用来获取容器中的组件

type Class = { new (...args: any[]): {} };
function getComponentInIOC(component: string | Class) {
    const name = component instanceof Function ? component.name : component;
    if (findComponentInIOCByName(name)) {
        throw new Error('no such component in container...');
    }
    return IOCMap[name];
}

模拟完之后对SpringBoot了解更深了…

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值