spring @Value原理及自定义实现

spring @Value原理及自定义实现,第1张


spring @Value原理及自定义实现

       

               

                                    

@Value 原理

         

@Value通过AutowiredAnnotationBeanPostProcessor完成属性注入

                    

        

Person

@Data
@Component
public class Person {

    @Value("瓜田李下")
    private String name;

    private Integer age;

}

         

AutowiredAnnotationBeanPostProcessor实例化调用栈

# AutowiredAnnotationBeanPostProcessor构造函数创建对象
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.(AutowiredAnnotationBeanPostProcessor.java:162)
	  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(NativeConstructorAccessorImpl.java:-1)
	  at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	  at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	  at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:211)

# SimpleInstantiationStrategy类
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87)

# AbstractAutowireCapableBeanFactory类
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1326)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1232)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)

# AbstractBeanFactory类
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$215.1489193907.getObject(Unknown Source:-1)

# DefaultSingletonBeanRegistry类
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
	  - locked <0xf9e> (a java.util.concurrent.ConcurrentHashMap)

# AbstractBeanFactory类
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213)

# PostProcessorRegistrationDelegate类
at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:237)

# AbstractApplicationContext
at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:762)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:567)
	  - locked <0xf9f> (a java.lang.Object)

# ServletWebServerApplicationContext类
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)

# SpringApplication类
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301)

# 项目启动入口
at com.example.demo.DemoApplication.main(DemoApplication.java:10)

           

属性注入调用栈

# AutowiredAnnotationBeanPostProcessor.postProcessProperties:执行属性注入
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)

# AbstractAutowireCapableBeanFactory类
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1431)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$211.1448805967.getObject(Unknown Source:-1)

# DefaultSingletonBeanRegistry类
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
	  - locked <0x1696> (a java.util.concurrent.ConcurrentHashMap)

# AbstractBeanFactory类
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)

# DefaultListableBeanFactory类
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:953)

# AbstractApplicationContext类
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
	  - locked <0x1697> (a java.lang.Object)

# ServletWebServerApplicationContext类
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)

# SpringApplication类
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301)

# 项目启动入口
at com.example.demo.DemoApplication.main(DemoApplication.java:10)

            

AutowiredAnnotationBeanPostProcessor

public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
    protected final Log logger = LogFactory.getLog(this.getClass());
    private final Set> autowiredAnnotationTypes = new LinkedHashSet(4);
    private String requiredParameterName = "required";
    private boolean requiredParameterValue = true;
    private int order = 2147483645;
    @Nullable
    private ConfigurableListableBeanFactory beanFactory;
    private final Set lookupMethodsChecked = Collections.newSetFromMap(new ConcurrentHashMap(256));
    private final Map, Constructor[]> candidateConstructorsCache = new ConcurrentHashMap(256);
    private final Map injectionMetadataCache = new ConcurrentHashMap(256);

    public AutowiredAnnotationBeanPostProcessor() {
        this.autowiredAnnotationTypes.add(Autowired.class);  //处理@Autowired注解
        this.autowiredAnnotationTypes.add(Value.class);      //处理@Value注解

        try {
            this.autowiredAnnotationTypes.add(ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
            this.logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
        } catch (ClassNotFoundException var2) {
        }

    }


    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
                          //属性注入
        InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs);

        try {
            metadata.inject(bean, beanName, pvs);  //属性注入
            return pvs;
        } catch (BeanCreationException var6) {
            throw var6;
        } catch (Throwable var7) {
            throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", var7);
        }
    }


********
内部类:AutowiredMethodElement处理方法注入

    private class AutowiredMethodElement extends InjectedElement {
        private final boolean required;
        private volatile boolean cached;
        @Nullable
        private volatile Object[] cachedMethodArguments;

        public AutowiredMethodElement(Method method, boolean required, @Nullable PropertyDescriptor pd) {
            super(method, pd);
            this.required = required;
        }

        protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
            if (!this.checkPropertySkipping(pvs)) {
                Method method = (Method)this.member;
                Object[] arguments;
                if (this.cached) {
                    try {
                        arguments = this.resolveCachedArguments(beanName);
                    } catch (NoSuchBeanDefinitionException var8) {
                        arguments = this.resolveMethodArguments(method, bean, beanName);
                    }
                } else {
                    arguments = this.resolveMethodArguments(method, bean, beanName);
                }

                if (arguments != null) {    //如果方法参数不为null,设置属性值
                    try {
                        ReflectionUtils.makeAccessible(method);
                        method.invoke(bean, arguments);
                    } catch (InvocationTargetException var7) {
                        throw var7.getTargetException();
                    }
                }

            }
        }

        private Object[] resolveCachedArguments(@Nullable String beanName) {
        private Object[] resolveMethodArguments(Method method, Object bean, @Nullable String beanName) {


********
内部类:AutowiredFieldElement处理字段注入

    private class AutowiredFieldElement extends InjectedElement {
        private final boolean required;
        private volatile boolean cached;
        @Nullable
        private volatile Object cachedFieldValue;

        public AutowiredFieldElement(Field field, boolean required) {
            super(field, (PropertyDescriptor)null);
            this.required = required;
        }

        protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
            Field field = (Field)this.member;
            Object value;
            if (this.cached) {
                try {
                    value = AutowiredAnnotationBeanPostProcessor.this.resolvedCachedArgument(beanName, this.cachedFieldValue);
                } catch (NoSuchBeanDefinitionException var7) {
                    value = this.resolveFieldValue(field, bean, beanName);
                }
            } else {
                value = this.resolveFieldValue(field, bean, beanName);
            }

            if (value != null) {     //如果value不为null,设置字段属性
                ReflectionUtils.makeAccessible(field);
                field.set(bean, value);
            }

        }

        private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {

        

InjectionMetadata

public class InjectionMetadata {

    public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
                      //属性注入
        Collection checkedElements = this.checkedElements;
        Collection elementsToIterate = checkedElements != null ? checkedElements : this.injectedElements;
        if (!((Collection)elementsToIterate).isEmpty()) {
            Iterator var6 = ((Collection)elementsToIterate).iterator();

            while(var6.hasNext()) {
                InjectionMetadata.InjectedElement element = (InjectionMetadata.InjectedElement)var6.next();
                element.inject(target, beanName, pvs);
            }           //属性注入
        }

    }


********
内部类:InjectedElement

   public abstract static class InjectedElement {
        protected final Member member;
        protected final boolean isField;
        @Nullable
        protected final PropertyDescriptor pd;
        @Nullable
        protected volatile Boolean skip;

        protected InjectedElement(Member member, @Nullable PropertyDescriptor pd) {
            this.member = member;
            this.isField = member instanceof Field;
            this.pd = pd;
        }

        public final Member getMember() {
            return this.member;
        }

        protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs) throws Throwable {
                       //属性注入,该方法在子类中进行了重写
            if (this.isField) {
                Field field = (Field)this.member;
                ReflectionUtils.makeAccessible(field);
                field.set(target, this.getResourceToInject(target, requestingBeanName));
            } else {
                if (this.checkPropertySkipping(pvs)) {
                    return;
                }

                try {
                    Method method = (Method)this.member;
                    ReflectionUtils.makeAccessible(method);
                    method.invoke(target, this.getResourceToInject(target, requestingBeanName));
                } catch (InvocationTargetException var5) {
                    throw var5.getTargetException();
                }
            }

        }

        protected final Class getResourceType() {

        protected final void checkResourceType(Class resourceType) {
        protected void clearPropertySkipping(@Nullable PropertyValues pvs) {
        protected boolean checkPropertySkipping(@Nullable PropertyValues pvs) {

        protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
            return null;
        }

        public boolean equals(@Nullable Object other) {
        public int hashCode() {
        public String toString() {

             

                                    

自定义注解

        

                      

         

application.properties

person.age=20

      

Person

@Data
@Component
public class Person {

    @CustomValue("瓜田李下")
    private String name;

    @CustomValue("${person.age}")
    private Integer age;
}

       

CustomBeanFactoryPostProcessor

@Configuration
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    private ConfigurableListableBeanFactory beanFactory;

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        beanFactory = configurableListableBeanFactory;
    }

    @Bean
    public AutowiredAnnotationBeanPostProcessor initAutowiredAnnotationBeanPostProcessor(){
        AutowiredAnnotationBeanPostProcessor autowiredAnnotationBeanPostProcessor = new AutowiredAnnotationBeanPostProcessor(){
            @Override
            public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
                ReflectionUtils.doWithLocalFields(bean.getClass(), field -> {
                    CustomValue customValue = field.getAnnotation(CustomValue.class);
                    if (customValue != null){
                        ReflectionUtils.makeAccessible(field);

                        String value = customValue.value();
                        if (value != null && !"".equals(value)){
                            if (!value.startsWith("$")){
                                field.set(bean,value);
                            }else {
                                TypeConverter typeConverter = new SimpleTypeConverter();
                                field.set(bean,typeConverter.convertIfNecessary(beanFactory.resolveEmbeddedValue(value),field.getType()));
                            }
                        }
                    }
                });

                return pvs;
            }

        };
        autowiredAnnotationBeanPostProcessor.setAutowiredAnnotationType(CustomValue.class);

        return autowiredAnnotationBeanPostProcessor;
    }
}

       

HelloController

@RestController
public class HelloController {

    @Resource
    private Person person;

    @RequestMapping("/hello")
    public String hello(){
        System.out.println(person);

        return person.toString();
    }
}

        

localhost:8080/hello:点击运行,控制台输出

2022-04-26 18:13:47.454  INFO 4224 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 774 ms
2022-04-26 18:13:47.725  INFO 4224 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2022-04-26 18:13:47.734  INFO 4224 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 1.414 seconds (JVM running for 1.865)
2022-04-26 18:13:53.480  INFO 4224 --- [nio-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2022-04-26 18:13:53.480  INFO 4224 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2022-04-26 18:13:53.481  INFO 4224 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
Person(name=瓜田李下, age=20)

      

                   

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/735541.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-27
下一篇 2022-04-27

发表评论

登录后才能评论

评论列表(0条)

保存