• Spring源码解析-AutowiredAnnotationBeanPostProcessor


    1.实现了BeanPostProcessor接口,可先看这个接口 ApplicationContext可以在自动检测BeanPostProcessor bean,在它创建完后可以创建任何的bean。

    public interface BeanPostProcessor {
        /*可以在bean实例化之前调用这个方法,类似init-method,
        *这个方法可以对bean进行操作
        */
        Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
    
        /**可以在bean实例化之后调用这个方法,类似init-method,
        *这个方法可以对bean进行操作
         */
        Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
    }

    简单实现自己的一个Processor

    public class MyBeanPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("MyBeanPostProcessor before->"+beanName);
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("MyBeanPostProcessor after -> "+beanName);
            return bean;
        }
    }

    spring-beans.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
    <bean id="student" class="org.lzyer.test.Student"></bean>
    <bean class="org.lzyer.test.MyBeanPostProcessor"/>
    </beans>

    测试类

    @Test
        public void testMyProcessor(){
            ApplicationContext ctx = new ClassPathXmlApplicationContext("spring/spring-beans.xml");
            Student student = (Student) ctx.getBean("student");
            System.out.println(student);
    
        }

    运行结果:

    MyBeanPostProcessor before->student
    MyBeanPostProcessor after -> student
    org.lzyer.test.Student@4d826d77

    2.AutowiredAnnotationBeanPostProcessor
    BeanPostProcessor的实现类,实现了自动注入属性、方法,可以使用jdk5的注解,默认使用spring的@Autowried和@Value注解。可以在spring配置文件中添加context:annotation-config和context:component-scan来注入AutowiredAnnotationBeanPostProcessor,另外注解的注入在xml配置文件注入之前。

    3.spring在哪里注入了BeanPostProcessor

    spring容器调用refresh方法中的

    // Register bean processors that intercept bean creation.
    registerBeanPostProcessors(beanFactory);
       /**
         * Instantiate and invoke all registered BeanPostProcessor beans,
         * respecting explicit order if given.
         * <p>Must be called before any instantiation of application beans.
         实例化并注入所有BeanPostProcessor,必须在bean实例化之前调用。
         */
        protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
            PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
        }

    4.回归到AutowiredAnnotationBeanPostProcessor
    构造方法

    public AutowiredAnnotationBeanPostProcessor() {
            this.autowiredAnnotationTypes.add(Autowired.class);
            this.autowiredAnnotationTypes.add(Value.class);
            try {
                this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
                        ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
                logger.info("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
            }
            catch (ClassNotFoundException ex) {
                // JSR-330 API not available - simply skip.
            }
    }

    构造方法中初始化注解的类型是@Autowried,@Value以及Annotation的子类
    里面包含2个内部类AutowiredFieldElement和AutowiredMethodElement分别处理字段和方法的注解。

    先看AutowiredFieldElement中inject方法

    protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
                Field field = (Field) this.member;
                try {
                    Object value;
                    if (this.cached) {//属性有缓存
                        value = resolvedCachedArgument(beanName, this.cachedFieldValue);
                    }
                    else {
                        DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
                        desc.setContainingClass(bean.getClass());
                        Set<String> autowiredBeanNames = new LinkedHashSet<String>(1);
                        TypeConverter typeConverter = beanFactory.getTypeConverter();
                        value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
                        synchronized (this) {
                            if (!this.cached) {//没有缓存
                                if (value != null || this.required) {
                                    this.cachedFieldValue = desc;
                                    registerDependentBeans(beanName, autowiredBeanNames);//注入依赖
                                    if (autowiredBeanNames.size() == 1) {
                                        String autowiredBeanName = autowiredBeanNames.iterator().next();
                                        if (beanFactory.containsBean(autowiredBeanName)) {
                                            //对字段进行类型匹配
                                            if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
                                                this.cachedFieldValue = new RuntimeBeanReference(autowiredBeanName);
                                            }
                                        }
                                    }
                                }
                                else {
                                    this.cachedFieldValue = null;
                                }
                                this.cached = true;
                            }
                        }
                    }
                    if (value != null) {
                        ReflectionUtils.makeAccessible(field);
                        field.set(bean, value);//反射注入值
                    }
                }
                catch (Throwable ex) {
                    throw new BeanCreationException("Could not autowire field: " + field, ex);
                }
            }
        }

    AutowiredMethodElement的inject方法

    protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
                if (checkPropertySkipping(pvs)) {
                    return;
                }
                Method method = (Method) this.member;
                try {
                    Object[] arguments;
                    if (this.cached) {//缓存方法参数
                        // Shortcut for avoiding synchronization...
                        arguments = resolveCachedArguments(beanName);
                    }
                    else {
                    //获取方法的所有参数
                        Class<?>[] paramTypes = method.getParameterTypes();
                        arguments = new Object[paramTypes.length];
                        DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length];
                        Set<String> autowiredBeanNames = new LinkedHashSet<String>(paramTypes.length);
                        TypeConverter typeConverter = beanFactory.getTypeConverter();
                        //参数处理
                        for (int i = 0; i < arguments.length; i++) {
                            MethodParameter methodParam = new MethodParameter(method, i);
                            DependencyDescriptor desc = new DependencyDescriptor(methodParam, this.required);
                            desc.setContainingClass(bean.getClass());
                            descriptors[i] = desc;
                            Object arg = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
                            if (arg == null && !this.required) {
                                arguments = null;
                                break;
                            }
                            arguments[i] = arg;
                        }
                        synchronized (this) {
                            if (!this.cached) {
                                if (arguments != null) {
                                    this.cachedMethodArguments = new Object[arguments.length];
                                    for (int i = 0; i < arguments.length; i++) {
                                        this.cachedMethodArguments[i] = descriptors[i];
                                    }
                                    registerDependentBeans(beanName, autowiredBeanNames);
                                    if (autowiredBeanNames.size() == paramTypes.length) {
                                        Iterator<String> it = autowiredBeanNames.iterator();
                                        for (int i = 0; i < paramTypes.length; i++) {
                                            String autowiredBeanName = it.next();
                                            if (beanFactory.containsBean(autowiredBeanName)) {
                                                if (beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
                                                    this.cachedMethodArguments[i] = new RuntimeBeanReference(autowiredBeanName);
                                                }
                                            }
                                        }
                                    }
                                }
                                else {
                                    this.cachedMethodArguments = null;
                                }
                                this.cached = true;
                            }
                        }
                    }
                    if (arguments != null) {
                        ReflectionUtils.makeAccessible(method);
                        method.invoke(bean, arguments);//反射调用方法
                    }
                }
                catch (InvocationTargetException ex) {
                    throw ex.getTargetException();
                }
                catch (Throwable ex) {
                    throw new BeanCreationException("Could not autowire method: " + method, ex);
                }
            }

    查找注解

    private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
            for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
                AnnotationAttributes ann = AnnotatedElementUtils.getAnnotationAttributes(ao, type.getName());
                if (ann != null) {
                    return ann;
                }
            }
            return null;
        }
  • 相关阅读:
    python笔记2-python常见数据类型(一)
    python笔记1-环境安装和基本语法
    selenium自动化脚本错误总结
    Postman-Post请求示例
    用PHP删除ftp下载导致的文件空行
    JS实现鼠标悬浮,显示内容
    asp.net中处理程序调用HttpContext.Current.Session获取值出错
    自动化创建tornado项目
    fabric运维
    Python3虚拟环境安装:virtualenv、virtualenvwralpper
  • 原文地址:https://www.cnblogs.com/lzeffort/p/7748611.html
Copyright © 2020-2023  润新知