
学过java的同学第一次在python中看到装饰器修饰函数或类时第一时间想到的就是java中注解如Resource 可能会觉得它们是一样的从我的理解来说其实是完全不一样的两个东西。它们形似而神不同。相同点它们的作用都是一样的可以通过它们在不改变原程序代码的情况下给程序增加一些新的功能实现AOP。不同点注解在文档中的解释是一个‘’标志‘’它的本质是用来给java编译器“看”的注释在java程序运行时,通过反射查找特定的‘’标志‘’将此标志作为判断条件做一些操作装饰器的本质是一个函数闭包函数将被装饰函数的地址一般用与被装饰函数相同的名字‘’李代桃僵‘’调用的其实是装饰器函数反回的函数地址。看看它们的使用吧装饰器的使用importtime# 定义一个装饰器增加打印程序运行时间的功能# 小提示python是解释性语言从上而下执行代码装饰器要写在被装饰函数的前面defoutter(func):defwrapper(*args,**kwargs):starttime.time()resfunc(*args,**kwargs)# 解构stoptime.time()print(stop-start)returnres,stop-start# 返回被装饰对象的返回值returnwrapperoutter# 在被装饰对象正上方单独一行写装饰器名(语法糖)等同于indexoutter(index)defindex(x,y):time.sleep(3)print(index %s,%s%(x,y))if__name____main__:resindex(1,3)print(res)程序运行结果index 1,33.0063154697418213(None, 3.0063154697418213)注解的使用模拟spring创建单例和多例对象1. 定义一个扫描注解ComponentScanpackagecom.spring;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;/** * 自定义扫描路径注解 */Retention(RetentionPolicy.RUNTIME)//注解的作用时间程序运行时Target(ElementType.TYPE)//注解使用范围publicinterfaceComponentScan{Stringvalue()default;}2. 定义一个配置类AppConfigpackagecom.service;importcom.zhaojun.spring.ComponentScan;ComponentScan(com.zhaojun.service)publicclassAppConfig{}3. 定义一个Bean注解Componentpackagecom.spring;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;/** * 自定义Bean注解 */Retention(RetentionPolicy.RUNTIME)//运行时Target(ElementType.TYPE)//注解使用范围publicinterfaceComponent{Stringvalue()default;}4. 定义一个Scope注解packagecom.spring;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;/** * 单例Bean或多例Bean */Retention(RetentionPolicy.RUNTIME)//运行时Target(ElementType.TYPE)//注解使用范围publicinterfaceScope{Stringvalue()default;}5. 定义一个类模拟spring容器packagecom.spring;importjava.io.File;importjava.lang.reflect.InvocationTargetException;importjava.net.URL;importjava.util.concurrent.ConcurrentHashMap;/** * 自定义Spring容器 */publicclassZhaojunApplicationContext{privateClassconfigClass;privateConcurrentHashMapString,BeanDefinitionbeanDefinitipnMapnewConcurrentHashMap();privateConcurrentHashMapString,ObjectsingleObjectsnewConcurrentHashMap();//单例Bean池publicZhaojunApplicationContext(ClassconfigClass){this.configClassconfigClass;//扫描if(configClass.isAnnotationPresent(ComponentScan.class)){ComponentScancomponentScanAnnotation(ComponentScan)configClass.getAnnotation(ComponentScan.class);//获取注解中配置的路径 com.zhaojun.serviceStringpathcomponentScanAnnotation.value();pathpath.replace(.,/);//com/zhaojun/serviceClassLoaderclassLoaderZhaojunApplicationContext.class.getClassLoader();//从classpath中获取class文件路径URLresourceclassLoader.getResource(path);FilefilenewFile(resource.getFile());//获取到指定文件夹或文件if(file.isDirectory()){File[]filesfile.listFiles();for(Filef:files){StringfileNamef.getAbsolutePath();if(fileName.endsWith(.class)){//转换全类名URLresource1ZhaojunApplicationContext.class.getResource(/);Stringpath1resource1.getPath();StringclassNamefileName.substring(path1.length()-1);//com\zhaojun\service\AppConfig.class//拿捏类名 com.zhaojun.service.AppConfigStringreplaceclassName.substring(0,className.indexOf(.class)).replace(\\,.);try{Class?clazzclassLoader.loadClass(replace);if(clazz.isAnnotationPresent(Component.class)){//获取bean的名字Componentcomponentclazz.getAnnotation(Component.class);StringbeanNamecomponent.value();//BeanDefinitionBeanDefinitionbeanDefinitionnewBeanDefinition();beanDefinition.setType(clazz);//判断多例还是单例Beanif(clazz.isAnnotationPresent(Scope.class)){ScopescopeAnnotationclazz.getAnnotation(Scope.class);StringscopscopeAnnotation.value();beanDefinition.setScope(scop);}else{beanDefinition.setScope(singleton);}//保存BeanbeanDefinitipnMap.put(beanName,beanDefinition);}}catch(ClassNotFoundExceptione){e.printStackTrace();}}}}}//实例化单例Beanfor(StringbeanName:beanDefinitipnMap.keySet()){BeanDefinitionbeanDefinitionbeanDefinitipnMap.get(beanName);if(beanDefinition.getScope().equals(singleton)){ObjectbeancreateBean(beanName,beanDefinition);singleObjects.put(beanName,bean);}}}//创建对象privateObjectcreateBean(StringbeanName,BeanDefinitionbeanDefinition){ClassclazzbeanDefinition.getType();try{Objectinstanceclazz.getConstructor().newInstance();//调无参构造创建实例returninstance;}catch(InstantiationExceptione){e.printStackTrace();}catch(IllegalAccessExceptione){e.printStackTrace();}catch(InvocationTargetExceptione){e.printStackTrace();}catch(NoSuchMethodExceptione){e.printStackTrace();}returnnull;}//自定义getBean方法publicObjectgetBean(StringbeanName){BeanDefinitionbeanDefinitionbeanDefinitipnMap.get(beanName);if(beanDefinitionnull){thrownewNullPointerException();}else{StringscopebeanDefinition.getScope();if(scope.equals(singleton)){ObjectbeansingleObjects.get(beanName);if(beannull){ObjectocreateBean(beanName,beanDefinition);singleObjects.put(beanName,o);}returnbean;}else{//多例returncreateBean(beanName,beanDefinition);}}}}6. 创建一个类用来测试packagecom.service;importcom.zhaojun.spring.Component;importcom.zhaojun.spring.Scope;Component(userService)Scope(prototype)publicclassUserService{}7. 测试packagecom.service;importcom.zhaojun.spring.ZhaojunApplicationContext;publicclassTest{publicstaticvoidmain(String[]args){ZhaojunApplicationContextzhaojunApplicationContextnewZhaojunApplicationContext(AppConfig.class);System.out.println(zhaojunApplicationContext.getBean(userService));System.out.println(zhaojunApplicationContext.getBean(userService));System.out.println(zhaojunApplicationContext.getBean(userService));System.out.println(zhaojunApplicationContext.getBean(userService));}}