大家好,今天小编来为大家解答怎么扫描网站源码分享这个问题,制作扫码网页很多人还不知道,现在让我们一起来看看吧!
前面文章@Autowired与@Resource区别主要对这两个注解的差异及使用方式进行了一个总结,本文将从源码分析被@Autowired、@Value和@Resource这三个注解修饰的属性和方法是如何被spring扫描到的。
其实负责扫描这三个注解的类是spring中的一种后置处理器BeanPostProcessor。其中,AutowiredAnnotationBeanPostProcessor负责扫描@Autowired和@Value这两个注解;CommonAnnotationBeanPostProcessor负责扫描@Resource这个注解。
平时开发中,我们通常将@Autowired、@Value和@Resource这三个注解添加到属性上,实际上这三个注解也可以应用在方法上,spring同样可以将它们扫描到。
下面将对核心源码进行简单分析:
@Autowired和@Value
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor34;Autowiredannotationisnotsupportedonstaticfields:&34;Autowiredannotationisnotsupportedonstaticmethods:&34;Autowiredannotationshouldonlybeusedonmethodswithparameters:&34;1&34;2&34;3&34;4&buildResourceMetadata()
privateInjectionMetadatabuildResourceMetadata(finalClass<?>clazz){\nList<InjectionMetadata.InjectedElement>elements=newArrayList<>();\nClass<?>targetClass=clazz;\n\ndo{\nfinalList<InjectionMetadata.InjectedElement>currElements=newArrayList<>();\n\nReflectionUtils.doWithLocalFields(targetClass,field->{\nif(webServiceRefClass!=null&&field.isAnnotationPresent(webServiceRefClass)){\nif(Modifier.isStatic(field.getModifiers())){\nthrownewIllegalStateException(&34;);\n}\ncurrElements.add(newWebServiceRefElement(field,field,null));\n}\nelseif(ejbRefClass!=null&&field.isAnnotationPresent(ejbRefClass)){\nif(Modifier.isStatic(field.getModifiers())){\nthrownewIllegalStateException(&34;);\n}\ncurrElements.add(newEjbRefElement(field,field,null));\n}\n//判断属性上是否有注解@Resource\nelseif(field.isAnnotationPresent(Resource.class)){\n//判断属性是否是静态\nif(Modifier.isStatic(field.getModifiers())){\nthrownewIllegalStateException(&34;);\n}\n//判断属性是否被忽略注入\nif(!this.ignoredResourceTypes.contains(field.getType().getName())){\ncurrElements.add(newResourceElement(field,field,null));\n}\n}\n});\n\nReflectionUtils.doWithLocalMethods(targetClass,method->{\nMethodbridgedMethod=BridgeMethodResolver.findBridgedMethod(method);\nif(!BridgeMethodResolver.isVisibilityBridgeMethodPair(method,bridgedMethod)){\nreturn;\n}\nif(method.equals(ClassUtils.getMostSpecificMethod(method,clazz))){\nif(webServiceRefClass!=null&&bridgedMethod.isAnnotationPresent(webServiceRefClass)){\nif(Modifier.isStatic(method.getModifiers())){\nthrownewIllegalStateException(&34;);\n}\nif(method.getParameterCount()!=1){\nthrownewIllegalStateException(&34;+method);\n}\nPropertyDescriptorpd=BeanUtils.findPropertyForMethod(bridgedMethod,clazz);\ncurrElements.add(newWebServiceRefElement(method,bridgedMethod,pd));\n}\nelseif(ejbRefClass!=null&&bridgedMethod.isAnnotationPresent(ejbRefClass)){\nif(Modifier.isStatic(method.getModifiers())){\nthrownewIllegalStateException(&34;);\n}\nif(method.getParameterCount()!=1){\nthrownewIllegalStateException(&34;+method);\n}\nPropertyDescriptorpd=BeanUtils.findPropertyForMethod(bridgedMethod,clazz);\ncurrElements.add(newEjbRefElement(method,bridgedMethod,pd));\n}\n//判断方法上是否有注解@Resource\nelseif(bridgedMethod.isAnnotationPresent(Resource.class)){\n//被@Resouce修饰的方法不能是静态的\nif(Modifier.isStatic(method.getModifiers())){\nthrownewIllegalStateException(&34;);\n}\nClass<?>[]paramTypes=method.getParameterTypes();\n//被@Resouce修饰的方法只能有1个参数\nif(paramTypes.length!=1){\nthrownewIllegalStateException(&34;+method);\n}\n//判断方法传递进来的bean是否被忽略注入\nif(!this.ignoredResourceTypes.contains(paramTypes[0].getName())){\nPropertyDescriptorpd=BeanUtils.findPropertyForMethod(bridgedMethod,clazz);\ncurrElements.add(newResourceElement(method,bridgedMethod,pd));\n}\n}\n}\n});\n\nelements.addAll(0,currElements);\ntargetClass=targetClass.getSuperclass();\n}\nwhile(targetClass!=null&&targetClass!=Object.class);\n\nreturnnewInjectionMetadata(clazz,elements);\n}
上面核心代码的主要逻辑如下:
(1)@Resource注解加在属性上:注解被加在属性字段上时,该属性字段不能被static修饰,否则直接报错;
(2)@Resource注解加在方法上:注解被加在方法上时,该方法必须只有1个参数,并且该方法不能被static修饰,否则直接报错。
(3)如果该类拥有父类,递归查找父类添加了这个注解的属性和方法,执行同样的扫描逻辑。
@Resource代码测试:
@Service\npublicclassInstanceAimplementsInstanceAPI{\n//正常注入\n@Resource\nprivateInstanceBinstanceB;\n\n//报错:@Resource不能修饰静态属性\n@Resource\nprivatestaticInstanceCinstanceC;\n\nprivateInstanceDinstanceD;\n//正常注入\n@Resource\npublicvoidinstanceD(InstanceDinstanceD){\nthis.instanceD=instanceD;\n}\n\nprivateInstanceEinstanceE;\n//报错:@Resource不能修饰静态方法\n@Resource\npublicstaticvoidinstanceE(InstanceEinstanceE){\ninstanceE=instanceE;\n}\n}
好了,关于怎么扫描网站源码分享和制作扫码网页的问题到这里结束啦,希望可以解决您的问题哈!
