SpringIOC-公共注解的支持
CommonAnnotationBeanPostProcessor类
CommonAnnotationBeanPostProcessor继承了InitDestroyAnnotationBeanPostProcessor,这两个注解是由这个父类完成解析的,在CommonAnnotationBeanPostProcessor构造函数中调用父类的方法setInitAnnotationType()和setDestroyAnnotationType()将这两个注解Class对象传递给父类。
对@PostConstruct和@PreDestroy注解的处理以及@Resources处理
构造方法
主要完成对@PostConstruct以及@PreDestroy扫描的设置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public CommonAnnotationBeanPostProcessor () { setOrder(Ordered.LOWEST_PRECEDENCE - 3 ); setInitAnnotationType(PostConstruct.class); setDestroyAnnotationType(PreDestroy.class); ignoreResourceType("javax.xml.ws.WebServiceContext" ); }
搜集注解
搜集@PostConstruct,@PreDestroy和@Resources的注解
postProcessMergedBeanDefinition
扫描类里面的属性或者方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Override public void postProcessMergedBeanDefinition (RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { super .postProcessMergedBeanDefinition(beanDefinition, beanType, beanName); InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null ); metadata.checkConfigMembers(beanDefinition); }
在实例化一个bean后此时还未进行依赖注入时,每个bean definition会被MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()方法执行一遍用来获取一些元数据来增加额外的功能,InitDestroyAnnotationBeanPostProcessor就是将bean定义了被@PostConstruct和@PreDestroy注解的方法缓存到一个Map中,供之后BeanPostProcessor.postProcessBeforeInitialization()和DestructionAwareBeanPostProcessor.postProcessBeforeDestruction()阶段可以直接获取这些方法来执行。
postProcessMergedBeanDefinition
调用父类的postProcessMergedBeanDefinition
父类是InitDestroyAnnotationBeanPostProcessor
扫描方法的initMethod和destroyMethod并将对应的注解封装成LifecycleMetadata
1 2 3 4 5 6 7 8 9 10 11 @Override public void postProcessMergedBeanDefinition (RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { LifecycleMetadata metadata = findLifecycleMetadata(beanType); metadata.checkConfigMembers(beanDefinition); }
根据class 获取获取initMethod和destroyMethod并封装成LifecycleMetadata
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 private LifecycleMetadata findLifecycleMetadata (Class<?> clazz) { if (this .lifecycleMetadataCache == null ) { return buildLifecycleMetadata(clazz); } LifecycleMetadata metadata = this .lifecycleMetadataCache.get(clazz); if (metadata == null ) { synchronized (this .lifecycleMetadataCache) { metadata = this .lifecycleMetadataCache.get(clazz); if (metadata == null ) { metadata = buildLifecycleMetadata(clazz); this .lifecycleMetadataCache.put(clazz, metadata); } return metadata; } } return metadata; }
findLifecycleMetadata方法内部主要调用buildLifecycleMetadata方法完成生命周期方法的,其余部分是缓存的操作不关心。
获取initMethod和destroyMethod 并封装成LifecycleMetadata
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 private LifecycleMetadata buildLifecycleMetadata (final Class<?> clazz) { if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this .initAnnotationType, this .destroyAnnotationType))) { return this .emptyLifecycleMetadata; } List<LifecycleElement> initMethods = new ArrayList <>(); List<LifecycleElement> destroyMethods = new ArrayList <>(); Class<?> targetClass = clazz; do { final List<LifecycleElement> currInitMethods = new ArrayList <>(); final List<LifecycleElement> currDestroyMethods = new ArrayList <>(); ReflectionUtils.doWithLocalMethods(targetClass, method -> { if (this .initAnnotationType != null && method.isAnnotationPresent(this .initAnnotationType)) { LifecycleElement element = new LifecycleElement (method); currInitMethods.add(element); if (logger.isTraceEnabled()) { logger.trace("Found init method on class [" + clazz.getName() + "]: " + method); } } if (this .destroyAnnotationType != null && method.isAnnotationPresent(this .destroyAnnotationType)) { currDestroyMethods.add(new LifecycleElement (method)); if (logger.isTraceEnabled()) { logger.trace("Found destroy method on class [" + clazz.getName() + "]: " + method); } } }); initMethods.addAll(0 , currInitMethods); destroyMethods.addAll(currDestroyMethods); targetClass = targetClass.getSuperclass(); } while (targetClass != null && targetClass != Object.class); return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this .emptyLifecycleMetadata : new LifecycleMetadata (clazz, initMethods, destroyMethods)); }
ReflectionUtils.doWithLocalMethods
所有的method进行回调
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public static void doWithLocalMethods (Class<?> clazz, MethodCallback mc) { Method[] methods = getDeclaredMethods(clazz, false ); for (Method method : methods) { try { mc.doWith(method); } catch (IllegalAccessException ex) { throw new IllegalStateException ("Not allowed to access method '" + method.getName() + "': " + ex); } } }
getDeclaredMethods
获取clazz以及接口的所有方法的数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 private static Method[] getDeclaredMethods(Class<?> clazz, boolean defensive) { Assert.notNull(clazz, "Class must not be null" ); Method[] result = declaredMethodsCache.get(clazz); if (result == null ) { try { Method[] declaredMethods = clazz.getDeclaredMethods(); List<Method> defaultMethods = findConcreteMethodsOnInterfaces(clazz); if (defaultMethods != null ) { result = new Method [declaredMethods.length + defaultMethods.size()]; System.arraycopy(declaredMethods, 0 , result, 0 , declaredMethods.length); int index = declaredMethods.length; for (Method defaultMethod : defaultMethods) { result[index] = defaultMethod; index++; } } else { result = declaredMethods; } declaredMethodsCache.put(clazz, (result.length == 0 ? EMPTY_METHOD_ARRAY : result)); } catch (Throwable ex) { throw new IllegalStateException ("Failed to introspect Class [" + clazz.getName() + "] from ClassLoader [" + clazz.getClassLoader() + "]" , ex); } } return (result.length == 0 || !defensive) ? result : result.clone(); }
LifecycleElement
LifecycleElement是一个内部类,保存了生命周期方法和方法的一个标识符,和一个invoke()方法用来调用被注解的方法。值得注意的是这个方法的可以是private的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 private static class LifecycleElement { private final Method method; private final String identifier; public LifecycleElement (Method method) { if (method.getParameterCount() != 0 ) { throw new IllegalStateException ("Lifecycle method annotation requires a no-arg method: " + method); } this .method = method; this .identifier = (Modifier.isPrivate(method.getModifiers()) ? ClassUtils.getQualifiedMethodName(method) : method.getName()); } public Method getMethod () { return this .method; } public String getIdentifier () { return this .identifier; } public void invoke (Object target) throws Throwable { ReflectionUtils.makeAccessible(this .method); this .method.invoke(target, (Object[]) null ); } @Override public boolean equals (@Nullable Object other) { if (this == other) { return true ; } if (!(other instanceof LifecycleElement)) { return false ; } LifecycleElement otherElement = (LifecycleElement) other; return (this .identifier.equals(otherElement.identifier)); } @Override public int hashCode () { return this .identifier.hashCode(); } }
checkConfigMembers
检测BeanDefinition和LifecycleElement的对应关系并给全局的checkedInitMethods,checkedDestroyMethods赋值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 public void checkConfigMembers (RootBeanDefinition beanDefinition) { Set<LifecycleElement> checkedInitMethods = new LinkedHashSet <>(this .initMethods.size()); for (LifecycleElement element : this .initMethods) { String methodIdentifier = element.getIdentifier(); if (!beanDefinition.isExternallyManagedInitMethod(methodIdentifier)) { beanDefinition.registerExternallyManagedInitMethod(methodIdentifier); checkedInitMethods.add(element); if (logger.isTraceEnabled()) { logger.trace("Registered init method on class [" + this .targetClass.getName() + "]: " + element); } } } Set<LifecycleElement> checkedDestroyMethods = new LinkedHashSet <>(this .destroyMethods.size()); for (LifecycleElement element : this .destroyMethods) { String methodIdentifier = element.getIdentifier(); if (!beanDefinition.isExternallyManagedDestroyMethod(methodIdentifier)) { beanDefinition.registerExternallyManagedDestroyMethod(methodIdentifier); checkedDestroyMethods.add(element); if (logger.isTraceEnabled()) { logger.trace("Registered destroy method on class [" + this .targetClass.getName() + "]: " + element); } } } this .checkedInitMethods = checkedInitMethods; this .checkedDestroyMethods = checkedDestroyMethods; }
小结 到这里位置已经对@PostConstruct和@PreDestroy注解进行了收集工作,将会在会面进行调用
根据@Resources注解查找实现了@Resources接口的属性和方法并封装成InjectionMetadata
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 private InjectionMetadata findResourceMetadata (String beanName, final Class<?> clazz, @Nullable PropertyValues pvs) { String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); InjectionMetadata metadata = this .injectionMetadataCache.get(cacheKey); if (InjectionMetadata.needsRefresh(metadata, clazz)) { synchronized (this .injectionMetadataCache) { metadata = this .injectionMetadataCache.get(cacheKey); if (InjectionMetadata.needsRefresh(metadata, clazz)) { if (metadata != null ) { metadata.clear(pvs); } metadata = buildResourceMetadata(clazz); this .injectionMetadataCache.put(cacheKey, metadata); } } } return metadata; }
获取属性和方法的@Resources注解并封装成InjectionMetadata
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 private InjectionMetadata buildResourceMetadata (final Class<?> clazz) { if (!AnnotationUtils.isCandidateClass(clazz, resourceAnnotationTypes)) { return InjectionMetadata.EMPTY; } List<InjectionMetadata.InjectedElement> elements = new ArrayList <>(); Class<?> targetClass = clazz; do { final List<InjectionMetadata.InjectedElement> currElements = new ArrayList <>(); ReflectionUtils.doWithLocalFields(targetClass, field -> { if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) { if (Modifier.isStatic(field.getModifiers())) { throw new IllegalStateException ("@WebServiceRef annotation is not supported on static fields" ); } currElements.add(new WebServiceRefElement (field, field, null )); } else if (ejbRefClass != null && field.isAnnotationPresent(ejbRefClass)) { if (Modifier.isStatic(field.getModifiers())) { throw new IllegalStateException ("@EJB annotation is not supported on static fields" ); } currElements.add(new EjbRefElement (field, field, null )); } else if (field.isAnnotationPresent(Resource.class)) { if (Modifier.isStatic(field.getModifiers())) { throw new IllegalStateException ("@Resource annotation is not supported on static fields" ); } if (!this .ignoredResourceTypes.contains(field.getType().getName())) { currElements.add(new ResourceElement (field, field, null )); } } }); ReflectionUtils.doWithLocalMethods(targetClass, method -> { Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) { return ; } if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) { if (webServiceRefClass != null && bridgedMethod.isAnnotationPresent(webServiceRefClass)) { if (Modifier.isStatic(method.getModifiers())) { throw new IllegalStateException ("@WebServiceRef annotation is not supported on static methods" ); } if (method.getParameterCount() != 1 ) { throw new IllegalStateException ("@WebServiceRef annotation requires a single-arg method: " + method); } PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz); currElements.add(new WebServiceRefElement (method, bridgedMethod, pd)); } else if (ejbRefClass != null && bridgedMethod.isAnnotationPresent(ejbRefClass)) { if (Modifier.isStatic(method.getModifiers())) { throw new IllegalStateException ("@EJB annotation is not supported on static methods" ); } if (method.getParameterCount() != 1 ) { throw new IllegalStateException ("@EJB annotation requires a single-arg method: " + method); } PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz); currElements.add(new EjbRefElement (method, bridgedMethod, pd)); } else if (bridgedMethod.isAnnotationPresent(Resource.class)) { if (Modifier.isStatic(method.getModifiers())) { throw new IllegalStateException ("@Resource annotation is not supported on static methods" ); } Class<?>[] paramTypes = method.getParameterTypes(); if (paramTypes.length != 1 ) { throw new IllegalStateException ("@Resource annotation requires a single-arg method: " + method); } if (!this .ignoredResourceTypes.contains(paramTypes[0 ].getName())) { PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz); currElements.add(new ResourceElement (method, bridgedMethod, pd)); } } } }); elements.addAll(0 , currElements); targetClass = targetClass.getSuperclass(); } while (targetClass != null && targetClass != Object.class); return InjectionMetadata.forElements(elements, clazz); }
上述代码是将@Resource注解的字段和方法以bean name为key,InjectedElement为value封装一个Map中,在属性注入阶段取出InjectedElement通过反射为目标字段或方法设置@Resource name指定的bean。InjectionMetadata封装的是一组InjectionMetadata.InjectedElement,这个InjectedElement会使用inject方法完成依赖注入,具体下面会讲到。
doWithLocalFields
获取所有的字段信息并进行回调
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public static void doWithLocalFields (Class<?> clazz, FieldCallback fc) { for (Field field : getDeclaredFields(clazz)) { try { fc.doWith(field); } catch (IllegalAccessException ex) { throw new IllegalStateException ("Not allowed to access field '" + field.getName() + "': " + ex); } } }
getDeclaredFields
获取clazz的所有的字段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 private static Field[] getDeclaredFields(Class<?> clazz) { Assert.notNull(clazz, "Class must not be null" ); Field[] result = declaredFieldsCache.get(clazz); if (result == null ) { try { result = clazz.getDeclaredFields(); declaredFieldsCache.put(clazz, (result.length == 0 ? EMPTY_FIELD_ARRAY : result)); } catch (Throwable ex) { throw new IllegalStateException ("Failed to introspect Class [" + clazz.getName() + "] from ClassLoader [" + clazz.getClassLoader() + "]" , ex); } } return result; }
checkConfigMembers
检测ConfigMembers并将InjectedElement集合赋值给全局的checkedElements
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public void checkConfigMembers (RootBeanDefinition beanDefinition) { Set<InjectedElement> checkedElements = new LinkedHashSet <>(this .injectedElements.size()); for (InjectedElement element : this .injectedElements) { Member member = element.getMember(); if (!beanDefinition.isExternallyManagedConfigMember(member)) { beanDefinition.registerExternallyManagedConfigMember(member); checkedElements.add(element); if (logger.isTraceEnabled()) { logger.trace("Registered injected element on class [" + this .targetClass.getName() + "]: " + element); } } } this .checkedElements = checkedElements; }
小结 到这里已经完成了对@Resource字段和方法的搜集,等待后面的注入
postProcessBeforeInitialization
bean会经过BeanPostProcessor.postProcessBeforeInitialization()方法处理,这个时候就会调用由@PostConstruct方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Override public Object postProcessBeforeInitialization (Object bean, String beanName) throws BeansException { LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass()); try { metadata.invokeInitMethods(bean, beanName); } catch (InvocationTargetException ex) { throw new BeanCreationException (beanName, "Invocation of init method failed" , ex.getTargetException()); } catch (Throwable ex) { throw new BeanCreationException (beanName, "Failed to invoke init method" , ex); } return bean; }
invokeInitMethods
调用搜集到的由@PostConstruct的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public void invokeInitMethods (Object target, String beanName) throws Throwable { Collection<LifecycleElement> checkedInitMethods = this .checkedInitMethods; Collection<LifecycleElement> initMethodsToIterate = (checkedInitMethods != null ? checkedInitMethods : this .initMethods); if (!initMethodsToIterate.isEmpty()) { for (LifecycleElement element : initMethodsToIterate) { if (logger.isTraceEnabled()) { logger.trace("Invoking init method on bean '" + beanName + "': " + element.getMethod()); } element.invoke(target); } } }
依赖注入
对@Resources进行依赖注入
postProcessProperties
对@Resources进行依赖注入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Override public PropertyValues postProcessProperties (PropertyValues pvs, Object bean, String beanName) { InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs); try { metadata.inject(bean, beanName, pvs); } catch (Throwable ex) { throw new BeanCreationException (beanName, "Injection of resource dependencies failed" , ex); } return pvs; }
inject
进行依赖注入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public void inject (Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { Collection<InjectedElement> checkedElements = this .checkedElements; Collection<InjectedElement> elementsToIterate = (checkedElements != null ? checkedElements : this .injectedElements); if (!elementsToIterate.isEmpty()) { for (InjectedElement element : elementsToIterate) { if (logger.isTraceEnabled()) { logger.trace("Processing injected element of bean '" + beanName + "': " + element); } element.inject(target, beanName, pvs); } } }
ResourceElement
依次调用之前保存的ResouceElement对象的inject方法。下面的重点就是放到了ResouceElement身上。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 private class ResourceElement extends LookupElement { private final boolean lazyLookup; public ResourceElement (Member member, AnnotatedElement ae, @Nullable PropertyDescriptor pd) { super (member, pd); Resource resource = ae.getAnnotation(Resource.class); String resourceName = resource.name(); Class<?> resourceType = resource.type(); this .isDefaultName = !StringUtils.hasLength(resourceName); if (this .isDefaultName) { resourceName = this .member.getName(); if (this .member instanceof Method && resourceName.startsWith("set" ) && resourceName.length() > 3 ) { resourceName = Introspector.decapitalize(resourceName.substring(3 )); } } else if (embeddedValueResolver != null ) { resourceName = embeddedValueResolver.resolveStringValue(resourceName); } if (Object.class != resourceType) { checkResourceType(resourceType); } else { resourceType = getResourceType(); } this .name = (resourceName != null ? resourceName : "" ); this .lookupType = resourceType; String lookupValue = resource.lookup(); this .mappedName = (StringUtils.hasLength(lookupValue) ? lookupValue : resource.mappedName()); Lazy lazy = ae.getAnnotation(Lazy.class); this .lazyLookup = (lazy != null && lazy.value()); } @Override protected Object getResourceToInject (Object target, @Nullable String requestingBeanName) { return (this .lazyLookup ? buildLazyResourceProxy(this , requestingBeanName) : getResource(this , requestingBeanName)); } }
从上面CommonAnnotationBeanPostProcessor的postProcessProperties()方法可知,属性的注入是调用ResourceElement的inject()方法,ResourceElement本身没有这个方法而是调用父类InjectedElement的inject方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 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, getResourceToInject(target, requestingBeanName)); } else { if (checkPropertySkipping(pvs)) { return ; } try { Method method = (Method) this .member; ReflectionUtils.makeAccessible(method); method.invoke(target, getResourceToInject(target, requestingBeanName)); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } } }
可以看到需要注入对象的来源方法getResourceToInject(),上面已经看到如果懒加载则使用buildLazyResourceProxy()方法将返回一个代理对象,等到使用到这个代理对象的方法时才会调用getResource()返回requestingBeanName指定的bean。下面先看getResource()方法。
getResource 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 protected Object getResource (LookupElement element, @Nullable String requestingBeanName) throws NoSuchBeanDefinitionException { if (StringUtils.hasLength(element.mappedName)) { return this .jndiFactory.getBean(element.mappedName, element.lookupType); } if (this .alwaysUseJndiLookup) { return this .jndiFactory.getBean(element.name, element.lookupType); } if (this .resourceFactory == null ) { throw new NoSuchBeanDefinitionException (element.lookupType, "No resource factory configured - specify the 'resourceFactory' property" ); } return autowireResource(this .resourceFactory, element, requestingBeanName); }
autowireResource
获取需要@Resources注入的对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 protected Object autowireResource (BeanFactory factory, LookupElement element, @Nullable String requestingBeanName) throws NoSuchBeanDefinitionException { Object resource; Set<String> autowiredBeanNames; String name = element.name; if (factory instanceof AutowireCapableBeanFactory) { AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory; DependencyDescriptor descriptor = element.getDependencyDescriptor(); if (this .fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) { autowiredBeanNames = new LinkedHashSet <>(); resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null ); if (resource == null ) { throw new NoSuchBeanDefinitionException (element.getLookupType(), "No resolvable resource object" ); } } else { resource = beanFactory.resolveBeanByName(name, descriptor); autowiredBeanNames = Collections.singleton(name); } } else { resource = factory.getBean(name, element.lookupType); autowiredBeanNames = Collections.singleton(name); } if (factory instanceof ConfigurableBeanFactory) { ConfigurableBeanFactory beanFactory = (ConfigurableBeanFactory) factory; for (String autowiredBeanName : autowiredBeanNames) { if (requestingBeanName != null && beanFactory.containsBean(autowiredBeanName)) { beanFactory.registerDependentBean(autowiredBeanName, requestingBeanName); } } } return resource; }
buildLazyResourceProxy
包装延迟加载对象 传入一个需要延时调用方法,并生成代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 protected Object buildLazyResourceProxy (final LookupElement element, final @Nullable String requestingBeanName) { TargetSource ts = new TargetSource () { @Override public Class<?> getTargetClass() { return element.lookupType; } @Override public boolean isStatic () { return false ; } @Override public Object getTarget () { return getResource(element, requestingBeanName); } @Override public void releaseTarget (Object target) { } }; ProxyFactory pf = new ProxyFactory (); pf.setTargetSource(ts); if (element.lookupType.isInterface()) { pf.addInterface(element.lookupType); } ClassLoader classLoader = (this .beanFactory instanceof ConfigurableBeanFactory ? ((ConfigurableBeanFactory) this .beanFactory).getBeanClassLoader() : null ); return pf.getProxy(classLoader); }
这个方法大段代码是为了实现AOP,但还是会调用target = targetSource.getTarget();获取实际对象的,可以看到懒加载机制的代理对象只有调用其方法才会去容器中获取实际的bean。
对象销毁
调用有@Destroy注解的销毁方法
postProcessBeforeDestruction
在bean销毁前会经过DestructionAwareBeanPostProcessor.postProcessBeforeDestruction()方法,在这个时候执行@PreDestroy方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @Override public void postProcessBeforeDestruction (Object bean, String beanName) throws BeansException { LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass()); try { metadata.invokeDestroyMethods(bean, beanName); } catch (InvocationTargetException ex) { String msg = "Destroy method on bean with name '" + beanName + "' threw an exception" ; if (logger.isDebugEnabled()) { logger.warn(msg, ex.getTargetException()); } else { logger.warn(msg + ": " + ex.getTargetException()); } } catch (Throwable ex) { logger.warn("Failed to invoke destroy method on bean with name '" + beanName + "'" , ex); } }
invokeDestroyMethods
调用销毁方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public void invokeDestroyMethods (Object target, String beanName) throws Throwable { Collection<LifecycleElement> checkedDestroyMethods = this .checkedDestroyMethods; Collection<LifecycleElement> destroyMethodsToUse = (checkedDestroyMethods != null ? checkedDestroyMethods : this .destroyMethods); if (!destroyMethodsToUse.isEmpty()) { for (LifecycleElement element : destroyMethodsToUse) { if (logger.isTraceEnabled()) { logger.trace("Invoking destroy method on bean '" + beanName + "': " + element.getMethod()); } element.invoke(target); } } }