j-spring 最轻量级的IOC (TS 版本)
纯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 回复
点个赞
@i5ting 谢谢啊
曾经我想过javaee规范出现的原因
- 必然性,从http,到容器,到servlet到jsp,然后到model1/2,ejb,ssh1/2,spring全家桶,这是技术抽象演进导致的
- node轻量级被推荐的原因,1)赶上devops时机好,不需要那么重的运维,2)经历了java的重,反而简单直接更受喜欢。3)这也是双刃剑,简单直接就必然会感觉配套不够完善,于是反反复复。。。。