码迷,mamicode.com
首页 > 编程语言 > 详细

Spring源码解析-AutowiredAnnotationBeanPostProcessor

时间:2017-10-29 00:41:02      阅读:344      评论:0      收藏:0      [点我收藏+]

标签:默认   length   ble   inter   cached   int   ima   schema   col   

 

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;
    }

 

Spring源码解析-AutowiredAnnotationBeanPostProcessor

标签:默认   length   ble   inter   cached   int   ima   schema   col   

原文地址:http://www.cnblogs.com/lzeffort/p/7748611.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!