博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring源码解析-AutowiredAnnotationBeanPostProcessor
阅读量:5967 次
发布时间:2019-06-19

本文共 9207 字,大约阅读时间需要 30 分钟。

hot3.png

Spring Bean 的生命周期

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

输入图片说明

BeanPostProcessor 接口方法

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

自定义的BeanProcessor 实现

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

运行结果:

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.     * 

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
) 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
autowiredBeanNames = new LinkedHashSet
(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
autowiredBeanNames = new LinkedHashSet
(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
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
type : this.autowiredAnnotationTypes) { AnnotationAttributes ann = AnnotatedElementUtils.getAnnotationAttributes(ao, type.getName()); if (ann != null) { return ann; } } return null; }

转载于:https://my.oschina.net/u/3421984/blog/1800615

你可能感兴趣的文章
批量删除用户--Shell脚本
查看>>
Eclipse Java @Override 报错
查看>>
知道双字节码, 如何获取汉字 - 回复 "pinezhou" 的问题
查看>>
Python高效编程技巧
查看>>
js中var self=this的解释
查看>>
linux的日志服务器关于屏蔽一些关键字的方法
查看>>
事情的两面性
查看>>
只要会营销,shi都能卖出去?
查看>>
sed单行处理命令奇偶行输出
查看>>
VC++深入详解学习笔记1
查看>>
安装配置discuz
查看>>
线程互互斥锁
查看>>
KVM虚拟机&openVSwitch杂记(1)
查看>>
win7下ActiveX注册错误0x80040200解决参考
查看>>
《.NET应用架构设计:原则、模式与实践》新书博客--试读-1.1-正确认识软件架构...
查看>>
2013 Linux领域年终盘点
查看>>
mysql多实例实例化数据库
查看>>
javascript 操作DOM元素样式
查看>>
Android 内存管理 &Memory Leak & OOM 分析
查看>>
HBase 笔记3
查看>>