Spring源码解析-AutowiredAnnotationBeanPostProcessor
Posted 92#
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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; }
以上是关于Spring源码解析-AutowiredAnnotationBeanPostProcessor的主要内容,如果未能解决你的问题,请参考以下文章