j-spring 最轻量级的IOC (TS 版本)
发布于 2 年前 作者 892280082 2790 次浏览 来自 分享

纯es6. github:j-spring

J-SPRING

Spring for TS

install

npm install j-spring

Usage

example

  import { spring } from "j-spring";

  it('autowired by special interface',()=>{

    interface A {
      v():number;
    }
    
    @Component
    class A1 implements A{
      v(): number {
        return 1;
      }
    }
    
    @Component
    class A2 implements A{
      v(): number {
        return 2;
      }
    }

    @Component
    class Application {
      
      @Autowired<A>({clazz:A1})
      a1:A;

      @Autowired<A>({clazz:A2})
      a2:A;

      main(c:number){
        return this.a1.v()+this.a2.v()+c;
      }
    }

    expect(spring.getBean(Application).main(3)).toBe(6);

  })

inject profile infomation

import { spring } from "j-spring";

describe('resource config load test',()=>{

  @Component
  class Student {
      @Value({path:'student.name',type:String})
      name:String;
      @Value({path:'student.age',type:Number})
      age:20;
      @Value({path:'student.city',type:String})
      city:String
      
      getMsg(){
          return ''+this.name+this.age+this.city;
      }
  }


  @Component
  class Application {

      @Value({path:'app.msg',type:String})
      appMsg:string;

      @Autowired({clazz:Student})
      student:Student;

      public main(){
          return this.appMsg+this.student.getMsg();
      }

  }

  it('A simple set value',()=>{

      spring.loadConfig({
        'app.msg':'hello',
        student:{
            name:'lina',
            age:20,
            city:'youda'
        }
      })

      expect(spring.launch(Application)).toEqual(`hello! my name is lina and 20 years old!`)

  })

})

aop

it('test sample Aop',()=>{

    import { spring,BeanPostProcessor } from "j-spring";

    //create Annotation
    const SupperCaseParamter = spring.methodAnnotationGenerator('SupperCaseParamter',{})

    @Component
    class SupperCaseParamterBeanProcessor implements BeanPostProcessor {
        getSort(): number {
            return 100;
        }
        postProcessBeforeInitialization(bean: any, _beanDefine: BeanDefine): Object {
            return bean;
        }
        postProcessAfterInitialization(bean: any, beanDefine: BeanDefine): Object {
            beanDefine.methodList.filter(m => m.hasAnnotation(SupperCaseParamter)).forEach(m => {
                
                const method = bean[m.name];

                bean[m.name] = function(...args:any[]){
                    return  method.apply(bean,args.map(a => {
                        return typeof a === 'string' ? (a as string).toUpperCase() : a;
                    }));
                }

            })
            return bean;
        }
        
    }

    @Component
    class Application {

        @SupperCaseParamter
        main(name:string){
            return name;
        }

    }

    expect(spring.bind(SupperCaseParamterBeanProcessor).getBean(Application).main('hello')).toEqual('HELLO');

})

costom annotation

import { spring, SpringContainer  } from '../src';

//diy annotation
const Controller = (path:string) => spring.classAnnotationGenerator('Controller',{path},Controller)

const ResfulApi = spring.classAnnotationGenerator('ResfulApi',{})

const Inject = (path:string) => spring.fieldAnnotationGenerator('Inject',{path},Inject);

const Get = (path:string) => spring.methodAnnotationGenerator('Get',{path},Get);

const Query = (fieldName:string) => spring.paramterAnnotationGenerator('Query',fieldName,{},Query)


describe('test custom annotation',()=>{

    it('it should be work',()=>{

        @Controller('/apiController')
        @ResfulApi
        class ApiController extends SpringContainer{

            @Inject('small pigBank')
            pigBank:String;
        
            @Get('/say')
            async say(@Query('user') user:string){
                return user;
            }

            main(){

                let result:any[] =[];

                this.getBeanDefineMap().forEach((_v,k) => {
                    const data = {
                        'class':k.clazz,
                        'anno-length':k.annotationList.length,
                        'anno-class':k.annotationList.map(a => a.clazz),
                        'anno-param-list':k.annotationList.map(a => a.params),
                        'field-list':k.fieldList.map(f => {
                            return {
                                'name':f.name,
                                'anno-list':f.annotationList.map(a => a.clazz),
                                'anno-param-list':f.annotationList.map(a => a.params)
                            }
                        }),
                        'method-list':k.methodList.map(m => {
                            return {
                                'name':m.name,
                                'anno-list':m.annotationList.map(m => m.clazz),
                                'anno-params':m.annotationList.map(m => m.params),
                                'field-list':m.paramterDefineList.map(pb => {
                                    return {
                                        'name':pb.name,
                                        'index':pb.index,
                                        'anno-list':pb.annotationList.map(a => a.clazz)
                                    }
                                })
                            }
                        })
                    }
                    result.push(data)
                })

                return result;
            }
        
        }

        expect(spring.launch(ApiController)).toEqual([
            {
                'class':ApiController,
                'anno-length':2,
                'anno-class':[ResfulApi,Controller],
                'anno-param-list':[{},{path:'/apiController'}],
                'field-list':[{
                    'name':'pigBank',
                    'anno-list':[Inject],
                    'anno-param-list':[{path:'small pigBank'}]
                }],
                'method-list':[
                    {
                        'name':'say',
                        'anno-list':[Get],
                        'anno-params':[{path:'/say'}],
                        'field-list':[
                            {
                                name:'user',
                                index:0,
                                'anno-list':[Query]
                            }
                        ]
                    },
                    
                ]
            }
        ])

    })

});

replace dependence

  it('replace autowired class',()=>{
    
    @Component
    class A {
      value(){
        return 1;
      }
    }    

    @Component
    class A100 extends A {
      value(): number {
        return 100;        
      }
    }

    @Component
    class Application {

      @Autowired({clazz:A})
      a:A;

      main(){
        return this.a.value();
      }

    }

    expect(spring.replaceClass(A,A100).launch(Application)).toBe(100)

  })
3 回复

曾经我想过javaee规范出现的原因

  • 必然性,从http,到容器,到servlet到jsp,然后到model1/2,ejb,ssh1/2,spring全家桶,这是技术抽象演进导致的
  • node轻量级被推荐的原因,1)赶上devops时机好,不需要那么重的运维,2)经历了java的重,反而简单直接更受喜欢。3)这也是双刃剑,简单直接就必然会感觉配套不够完善,于是反反复复。。。。
回到顶部