如 @Autowire @Value 等是什么时候执行,在那个类,什么时候触发的。

那么@Autowire @Value 是什么时候放入的呢

1、通过Ctrl+Shift+R进行全局查找

查找到后就打断点

image.png

2、debug进来,通过调用栈进行反推

image.png

3、Autowired和Value类都放入集合中

image.png
image.png

4、从调用栈中发现通过构造函数创建对象时加入的

通过doCreateBean开始看吧
image.png
image.png

image.png

image.png
image.png

image.png

因为上面经过层层调用都是通过构造方法去创建实例的。上面已经调用无参构造创建了实例
那么返回的就是这个实例对象。实例里的集合包含着Autowired和Value类

AutowiredAnnotationBeanPostProcessor 类,这个postProcessor的服务会处理@Autowired 和@Value来个注解

image.png

那么如何获取里面的属性值的呢?

1、全局快速搜索,并打断点

image.png

2、然后debug进行发现没得哦,

好像没有进入任何的debug断点。那么只能重新从刚刚加入的断点处继续。
换一个思路,刚刚Value和Autowirted都加入到了集合,那么就可能会用到这个结合的啊
所以在所有在出现集合的地方打断点。再重新debug进来image.png

3、重新debug进来,进到一个遍历autowiredAnnotationTypes的方法里面

image.png

image.png

到这里就能得到注解对应的属性,及对应的值了。那么怎么晓得注解什么时候触发呢?

4、结合调用栈进行反推

image.png

image.png

image.png

image.png
image.png

image.png

重点:到此,整个第4点通过反推,就晓得如何获取其目标类的属性(通过反射 获取遍历获取所有属性),获取到属性后,通过lambda表达式中的findAutowiredAnnotation()方法去获取对应的属性的值

5、再看如何通过属性获取注解上面的值

从上面第4点的反推中,发现通过类的全限定类名,再运用反射获取属性的方式。取出属性,及属性上的值。
哪里有获取到注解上面的值呢?
image.png

6、看返回的结果是什么

从截图发现,返回的值就是注解上面的值,而且是通过参数传入的,只不过通过这个方法进行获取而已。
image.png

结论,通过上面的反推3,看出,通过反射,获取到了各个属性及其属性上对应注解的值

那么如何通过参数获取的需要的注解的值

image.png
image.png

image.png
image.png
image.png
image.png

image.png

image.png

那么@Autowire @Value什么时候触发执行的呢?

通过调用栈反推, 看名字, 找自动元数据
image.png

image.png

image.png

如何实现自定义的注解

然后发现网上这个写的挺详细的,拷贝下来以便加深理解,及复习

1、自定义@MyValue注解类

  1. @Target(ElementType.FIELD)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. public @interface MyValue {
  5. String value() default "";
  6. }

2、自定义使用@MyValue注解的属性的类

  1. @Component
  2. @Data
  3. public class Car {
  4. @MyValue(value = "布加迪")
  5. String name;
  6. @MyValue(value = "6666w")
  7. String price;
  8. static {
  9. System.out.println("static car...");
  10. }
  11. }

3、自定义后置处理器 MyPostProcessor

  1. @Component
  2. public class MyPostProcess implements SmartInitializingSingleton,BeanFactoryPostProcessor {
  3. BeanFactory beanFactory;
  4. @Override
  5. public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
  6. System.out.println("this is factory...");
  7. this.beanFactory = beanFactory;
  8. }
  9. @Override
  10. public void afterSingletonsInstantiated() {
  11. System.out.println("process afterSingletons...");
  12. // 处理@MyValue注解
  13. Car car = beanFactory.getBean(Car.class);
  14. // 通过对类的Class对象进行反射,获取其属性
  15. Stream.of(Car.class.getDeclaredFields())
  16. // 如果注解的属性不为空
  17. .filter(field -> field.getAnnotation(MyValue.class) != null)
  18. // 用lambda表达式,通过反射获取注解及其属性
  19. .forEach(field -> {
  20. MyValue myValue = field.getAnnotation(MyValue.class);
  21. try {
  22. field.set(car,myValue.value()); // 属性注入.
  23. } catch (IllegalAccessException e) {
  24. e.printStackTrace();
  25. }
  26. // 设置属性
  27. // System.out.println(field.getName());
  28. //
  29. //1. 方法2,反射找到对应的set方法做属性的设置
  30. /*String fieldName = field.getName();
  31. Class<?> type = field.getType();
  32. String setMethodName = "set".concat(fieldName.substring(0,1).toUpperCase()).concat(fieldName.substring(1));
  33. try {
  34. Method method = Car.class.getMethod(setMethodName, type);
  35. method.invoke(car,myValue.value());
  36. } catch (Exception e) {
  37. e.printStackTrace();
  38. }*/
  39. });
  40. System.out.println("car: "+ car);
  41. }
  42. }

打印结果: Car(name=布加迪, price=6666w) 完成自定义属性注解.

这里需要重点说如一下,自定义后置处理器,实现SmartInitializingSingleton,BeanFactoryPostProcessor 接口,需要重写postProcessBeanFactory() 和 afterSingletonsInstantiated() 方法
其中postProcessBeanFactory() 方法块,在sping初始化bean之前就会调用执行
afterSingletonsInstantiated() 方法会在完成bean的创建及管理之后执行.
[

](https://blog.csdn.net/mapeng765441650/article/details/105477160/)

网上对getDeclaredAnnotations说的解析

java.lang.reflect.Method.getDeclaredAnnotations()方法返回该元素上直接存在的所有注释

方法的用法

主要是:
Method[] methods = SampleClass.class.getMethods(); // 获取所有方法
Annotation[] annotations = methods[0].getDeclaredAnnotations();// 通过反射获取方法上的注解

  1. import java.lang.annotation.Annotation;
  2. import java.lang.annotation.Retention;
  3. import java.lang.annotation.RetentionPolicy;
  4. import java.lang.reflect.Method;
  5. public class MethodDemo {
  6. public static void main(String[] args) {
  7. Method[] methods = SampleClass.class.getMethods();
  8. Annotation[] annotations = methods[0].getDeclaredAnnotations();
  9. for(Annotation annotation : annotations){
  10. if(annotation instanceof CustomAnnotation){
  11. CustomAnnotation customAnnotation = (CustomAnnotation) annotation;
  12. System.out.println("name: " + customAnnotation.name());
  13. System.out.println("value: " + customAnnotation.value());
  14. }
  15. }
  16. }
  17. }
  18. @CustomAnnotation(name="SampleClass", value = "Sample Class Annotation")
  19. class SampleClass {
  20. private String sampleField;
  21. @CustomAnnotation(name="getSampleMethod", value = "Sample Method Annotation")
  22. public String getSampleField() {
  23. return sampleField;
  24. }
  25. public void setSampleField(String sampleField) {
  26. this.sampleField = sampleField;
  27. }
  28. }
  29. @Retention(RetentionPolicy.RUNTIME)
  30. @interface CustomAnnotation {
  31. public String name();
  32. public String value();
  33. }

得到的结果如下:
name: getSampleMethod value: Sample Method Annotation
[

](https://blog.csdn.net/mapeng765441650/article/details/105477160/)

时序图@Value&@Autowired.jpg

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

反射的相关类详解
https://www.yiibai.com/javareflect/javareflect_method_getdeclaredannotations.html