当前位置: 首页 > news >正文

网站搭建哪里找最好微信开发者平台api

网站搭建哪里找最好,微信开发者平台api,广州番禺区天气,四川建筑职业学校官网教务网a、在createBean中又是主要做了什么事情#xff1f; 完成bean得创建#xff0c;填充属性、循环依赖 、aop等一系列过程 1、createBean() 在createBean中主要干了3件事情 1、解析class - resolveBeanClass() 2、验证及准备覆盖的方法,lookup-method replace-method - …a、在createBean中又是主要做了什么事情 完成bean得创建填充属性、循环依赖 、aop等一系列过程 1、createBean() 在createBean中主要干了3件事情 1、解析class - resolveBeanClass() 2、验证及准备覆盖的方法,lookup-method replace-method - prepareMethodOverrides() 3、实例化之前得解析工作也就是 给BPP一个机会来返回代理对象替换普通对象 AOP中有一些对象 就是再此处生成resolveBeforeInstantiation() protected Object createBean(String beanName, RootBeanDefinition mbd, Nullable Object[] args)throws BeanCreationException {if (logger.isTraceEnabled()) {logger.trace(Creating instance of bean beanName );}RootBeanDefinition mbdToUse mbd;// Make sure bean class is actually resolved at this point, and// clone the bean definition in case of a dynamically resolved Class// which cannot be stored in the shared merged bean definition.// 锁定class根据设置的class属性或者根据className来解析classClass? resolvedClass resolveBeanClass(mbd, beanName);// 进行条件筛选重新赋值RootBeanDefinition,并设置BeanClass属性if (resolvedClass ! null !mbd.hasBeanClass() mbd.getBeanClassName() ! null) {// 重新创建一个RootBeanDefinition对象mbdToUse new RootBeanDefinition(mbd);// 设置BeanClass属性值mbdToUse.setBeanClass(resolvedClass);}// Prepare method overrides.// 验证及准备覆盖的方法,lookup-method replace-method当需要创建的bean对象中包含了lookup-method和replace-method标签的时候会产生覆盖操作try {mbdToUse.prepareMethodOverrides();}catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName, Validation of method overrides failed, ex);}try {// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.// 给BeanPostProcessors一个机会来返回代理来替代真正的实例应用实例化前的前置处理器,用户自定义动态代理的方式针对于当前的被代理类需要经过标准的代理流程来创建对象Object bean resolveBeforeInstantiation(beanName, mbdToUse);if (bean ! null) {return bean;}}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,BeanPostProcessor before instantiation of bean failed, ex);}try {// 实际创建bean的调用Object beanInstance doCreateBean(beanName, mbdToUse, args);if (logger.isTraceEnabled()) {logger.trace(Finished creating instance of bean beanName );}return beanInstance;}catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {// A previously detected exception with proper bean creation context already,// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.throw ex;}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, Unexpected exception during bean creation, ex);}}1.1 resolveBeanClass() 锁定class根据设置的class属性或者根据className 来解析 Class Nullable protected Class? resolveBeanClass(RootBeanDefinition mbd, String beanName, Class?... typesToMatch) {if (mbd.hasBeanClass()) {return mbd.getBeanClass();}if (System.getSecurityManager() ! null) {return AccessController.doPrivileged((PrivilegedExceptionActionClass?)() - doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());} else {return doResolveBeanClass(mbd, typesToMatch);} }Nullable private Class? doResolveBeanClass(RootBeanDefinition mbd, Class?... typesToMatch) {ClassLoader beanClassLoader getBeanClassLoader();ClassLoader classLoaderToUse beanClassLoader;if (!ObjectUtils.isEmpty(typesToMatch)) {// When just doing type checks (i.e. not creating an actual instance yet),// use the specified temporary class loader (e.g. in a weaving scenario).ClassLoader tempClassLoader getTempClassLoader();if (tempClassLoader ! null) {classLoaderToUse tempClassLoader;if (tempClassLoader instanceof DecoratingClassLoader) {DecoratingClassLoader dcl (DecoratingClassLoader) tempClassLoader;for (Class? typeToMatch : typesToMatch) {dcl.excludeClass(typeToMatch.getName());}}}}String className mbd.getBeanClassName();if (className ! null) {Object evaluated evaluateBeanDefinitionString(className, mbd);if (!className.equals(evaluated)) {// A dynamically resolved expression, supported as of 4.2...if (evaluated instanceof Class) {return (Class?) evaluated;} else if (evaluated instanceof String) {return ClassUtils.forName((String) evaluated, classLoaderToUse);}}// When resolving against a temporary class loader, exit early in order// to avoid storing the resolved Class in the bean definition.if (classLoaderToUse ! beanClassLoader) {return ClassUtils.forName(className, classLoaderToUse);}}return mbd.resolveBeanClass(beanClassLoader); }1.2 prepareMethodOverrides() 对Override属性标记及验证在 Spring 配置中存在 lookup - method 和 replace - method 两个配置功能而这两个配置的加载其实就是将配置统一存放在 BeanDefinition 中的 methodOverrides 属性里这两个功能实现原理其实是在 bean 实例化的时候如果检测到存在 methodOverrides 属性会动态地为当前 bean 生成代理并使用对应的拦截器为 bean 做增强处理。 对于方法的匹配来讲如果一个类中存在若干个重载方法那么在函数调用及增强的时候还需要根据参数类型进行匹配来最终确认当前调用的到底是哪个函数。如果当前类中的方法只有一个那么就设置重载该方法没有被重载这样在后续调用的时候便可以直接使用找到的方法而不需要进行方法的参数匹配验证了而且还可以提前对方法存在性进行验证。 /*** Validate and prepare the method overrides defined for this bean. 验证并准备为此 bean 定义的方法覆盖。* Checks for existence of a method with the specified name. 检查具有指定名称的方法是否存在。* throws BeanDefinitionValidationException in case of validation failure*/public void prepareMethodOverrides(){// Check that lookup methods exist and determine their overloaded status.if (hasMethodOverrides()) {// MethodOverrides methodOverrides new MethodOverrides();// final SetMethodOverride overrides new CopyOnWriteArraySet();getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);}}/*** Validate and prepare the given method override.* Checks for existence of a method with the specified name,* marking it as not overloaded if none found.* param mo the MethodOverride object to validate* throws BeanDefinitionValidationException in case of validation failure*/protected void prepareMethodOverride(MethodOverride mo) {// 获取对应方法名的个数int count ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());if (count 1) {// 标记 MethodOverrides 为未覆盖避免参数类型检查的开销// Mark override as not overloaded, to avoid the overhead of arg type checking.mo.setOverloaded(false);}} 1.3 resolveBeforeInstantiation() 实例化的前置处理对后处理器中的所有 InstantiationAwareBeanPostProcessor 类型的后处理器 调用 postProcessBeforelnstantiation() 和 BeanPostProcessor 的 postProcessAfterInitialization()。 /*** Apply before-instantiation post-processors, resolving whether there is a* before-instantiation shortcut for the specified bean.* param beanName the name of the bean* param mbd the bean definition for the bean* return the shortcut-determined bean instance, or {code null} if none*/Nullableprotected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {Object bean null;// 如果尚未被解析if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {// Make sure bean class is actually resolved at this point.if (!mbd.isSynthetic() hasInstantiationAwareBeanPostProcessors()) {Class? targetType determineTargetType(beanName, mbd);if (targetType ! null) {bean applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);if (bean ! null) {bean applyBeanPostProcessorsAfterInitialization(bean, beanName);}}}mbd.beforeInstantiationResolved (bean ! null);}return bean;} 1.3.1 applyBeanPostProcessorsBeforeInstantiation() 在 bean 的实例化前会调用后处理器的方法进行处理 bean 的实例化前调用给子类一个修改 BeanDefinition 的机会也就是说当程序经过这个方法后 bean 可能已经不是我们认为的 bean 了而是或许成为了一个经过处理的代理 bean 可能是通过 cglib 生成的也可能是通过其他技术生成的。aop的相关有些类就是在这边提前处理了。 这里也可以自己扩展不过一般用不到 扩展点1实现InstantiationAwareBeanPostProcessor 接口 public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {/*** 实例化之前的操作*/Overridepublic Object postProcessBeforeInstantiation(Class? beanClass, String beanName) throws BeansException {// 这里也可以返回普通对象System.out.println(当前beanName beanName -- 执行postProcessBeforeInstantiation 实例化之前);if (beanClass MyConfig.class) {// 创建动态代理类的增强类Enhancer enhancer new Enhancer();// 设置类加载器enhancer.setClassLoader(beanClass.getClassLoader());// 设置被动态代理类所代理的 被代理类enhancer.setSuperclass(beanClass);// 设置方法拦截器enhancer.setCallback(new QzkMethodInterceptor());// 创建代理类BeforeInstantiation beforeInstantiation (BeforeInstantiation) enhancer.create();System.out.println(创建代理对象 beforeInstantiation);return beforeInstantiation;}return nulll;}/*** 实例化之后的操作*/Overridepublic boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {// MyConfig config (MyConfig)bean; 这里也可以调整 属性的值或者其他操作//其实就是 相当于 经历spring的完整的对象创建过程然后调整属性的值的一个操作config.age10;System.out.println(当前beanName beanName -- 执行postProcessAfterInstantiation 实例化之后);return false;}/*** 对当前属性值的一个相关处理工作*/Overridepublic PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {System.out.println(当前beanName beanName -- 执行postProcessProperties 属性值的处理);return pvs;}/*** 初始化之前的做哪些操作*/Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println(当前beanName beanName -- 执行postProcessBeforeInitialization 初始化之前);return bean;}/*** 初始化之后做哪些操作*/Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println(当前beanName beanName -- 执行postProcessAfterInitialization 初始化之后);return bean;} }1.3.2 applyBeanPostProcessorsAfterInitialization() 实例化后的后处理器应用Spring 中的规则是在 bean 的初始化后尽可能保证将注册的后处理器的 postProcessAfterlnitialization() 应用到该 bean 中因为如果返回的 bean 不为空那么便不会再次经历普通 bean 的创建过程所以只能在这里应用后处理器的 postProcessAfterInitialization()。 2、doCreateBean() 整体的流程如下每个细节过程还有具体的图整体的可能看不清 protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.// 这个beanWrapper是用来持有创建出来的bean对象的BeanWrapper instanceWrapper null;// 获取factoryBean实例缓存if (mbd.isSingleton()) {// 如果是单例对象从factorybean实例缓存中移除当前bean定义信息instanceWrapper this.factoryBeanInstanceCache.remove(beanName);}// 没有就创建实例if (instanceWrapper null) {// 根据执行bean使用对应的策略创建新的实例如工厂方法构造函数主动注入、简单初始化instanceWrapper createBeanInstance(beanName, mbd, args);}// 从包装类中获取原始beanObject bean instanceWrapper.getWrappedInstance();// 获取具体的bean对象的Class属性Class? beanType instanceWrapper.getWrappedClass();// 如果不等于NullBean类型那么修改目标类型if (beanType ! NullBean.class) {mbd.resolvedTargetType beanType;}// Allow post-processors to modify the merged bean definition.// 允许beanPostProcessor去修改合并的beanDefinitionsynchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {// MergedBeanDefinitionPostProcessor后置处理器修改合并bean的定义applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,Post-processing of merged bean definition failed, ex);}mbd.postProcessed true;}}// Eagerly cache singletons to be able to resolve circular references// even when triggered by lifecycle interfaces like BeanFactoryAware.// 判断当前bean是否需要提前曝光单例允许循环依赖当前bean正在创建中检测循环依赖boolean earlySingletonExposure (mbd.isSingleton() this.allowCircularReferences isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace(Eagerly caching bean beanName to allow for resolving potential circular references);}// 为避免后期循环依赖可以在bean初始化完成前将创建实例的ObjectFactory加入工厂addSingletonFactory(beanName, () - getEarlyBeanReference(beanName, mbd, bean));}// Initialize the bean instance.// 初始化bean实例Object exposedObject bean;try {// 对bean的属性进行填充将各个属性值注入其中可能存在依赖于其他bean的属性则会递归初始化依赖的beanpopulateBean(beanName, mbd, instanceWrapper);// 执行初始化逻辑exposedObject initializeBean(beanName, exposedObject, mbd);}catch (Throwable ex) {if (ex instanceof BeanCreationException beanName.equals(((BeanCreationException) ex).getBeanName())) {throw (BeanCreationException) ex;}else {throw new BeanCreationException(mbd.getResourceDescription(), beanName, Initialization of bean failed, ex);}}if (earlySingletonExposure) {// 从缓存中获取具体的对象Object earlySingletonReference getSingleton(beanName, false);// earlySingletonReference只有在检测到有循环依赖的情况下才会不为空if (earlySingletonReference ! null) {// 如果exposedObject没有在初始化方法中被改变也就是没有被增强if (exposedObject bean) {exposedObject earlySingletonReference;}else if (!this.allowRawInjectionDespiteWrapping hasDependentBean(beanName)) {String[] dependentBeans getDependentBeans(beanName);SetString actualDependentBeans new LinkedHashSet(dependentBeans.length);for (String dependentBean : dependentBeans) {// 返回false说明依赖还没实例化好if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}// 因为bean创建后所依赖的bean一定是已经创建的// actualDependentBeans不为空则表示当前bean创建后其依赖的bean却没有全部创建完也就是说存在循环依赖if (!actualDependentBeans.isEmpty()) {throw new BeanCurrentlyInCreationException(beanName,Bean with name beanName has been injected into other beans [ StringUtils.collectionToCommaDelimitedString(actualDependentBeans) ] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using getBeanNamesForType with the allowEagerInit flag turned off, for example.);}}}}// Register bean as disposable.try {// 注册bean对象方便后续在容器销毁的时候销毁对象registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, Invalid destruction signature, ex);}return exposedObject;}2.1 createBeanInstance() protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Nullable Object[] args) {// Make sure bean class is actually resolved at this point.// 确认需要创建的bean实例的类可以实例化Class? beanClass resolveBeanClass(mbd, beanName);// 确保class不为空并且访问权限是publicif (beanClass ! null !Modifier.isPublic(beanClass.getModifiers()) !mbd.isNonPublicAccessAllowed()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,Bean class isnt public, and non-public access not allowed: beanClass.getName());}// 判断当前beanDefinition中是否包含实例供应器此处相当于一个回调方法利用回调方法来创建beanSupplier? instanceSupplier mbd.getInstanceSupplier();if (instanceSupplier ! null) {return obtainFromSupplier(instanceSupplier, beanName);}// 如果工厂方法不为空则使用工厂方法初始化策略if (mbd.getFactoryMethodName() ! null) {return instantiateUsingFactoryMethod(beanName, mbd, args);}// 一个类可能有多个构造器所以Spring得根据参数个数、类型确定需要调用的构造器// 在使用构造器创建实例后Spring会将解析过后确定下来的构造器或工厂方法保存在缓存中避免再次创建相同bean时再次解析// Shortcut when re-creating the same bean...// 标记下防止重复创建同一个beanboolean resolved false;// 是否需要自动装配boolean autowireNecessary false;// 如果没有参数if (args null) {synchronized (mbd.constructorArgumentLock) {// 因为一个类可能由多个构造函数所以需要根据配置文件中配置的参数或传入的参数来确定最终调用的构造函数。// 因为判断过程会比较所以spring会将解析、确定好的构造函数缓存到BeanDefinition中的resolvedConstructorOrFactoryMethod字段中。// 在下次创建相同时直接从RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod缓存的值获取避免再次解析if (mbd.resolvedConstructorOrFactoryMethod ! null) {resolved true;autowireNecessary mbd.constructorArgumentsResolved;}}}// 有构造参数的或者工厂方法if (resolved) {// 构造器有参数if (autowireNecessary) {// 构造函数自动注入return autowireConstructor(beanName, mbd, null, null);}else {// 使用默认构造函数构造return instantiateBean(beanName, mbd);}}// Candidate constructors for autowiring?// 从bean后置处理器中为自动装配寻找构造方法, 有且仅有一个有参构造或者有且仅有Autowired注解构造Constructor?[] ctors determineConstructorsFromBeanPostProcessors(beanClass, beanName);// 以下情况符合其一即可进入// 1、存在可选构造方法// 2、自动装配模型为构造函数自动装配// 3、给BeanDefinition中设置了构造参数值// 4、有参与构造函数参数列表的参数if (ctors ! null || mbd.getResolvedAutowireMode() AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {return autowireConstructor(beanName, mbd, ctors, args);}// Preferred constructors for default construction?// 找出最合适的默认构造方法ctors mbd.getPreferredConstructors();if (ctors ! null) {// 构造函数自动注入return autowireConstructor(beanName, mbd, ctors, null);}// No special handling: simply use no-arg constructor.// 使用默认无参构造函数创建对象如果没有无参构造且存在多个有参构造且没有AutoWired注解构造会报错return instantiateBean(beanName, mbd);}总结 bean对象的创建方式 2.2 applyMergedBeanDefinitionPostProcessors() 应用MergedBeanDefinitionPostProcessors类型的beanPostProcessor到指定的beanDefinition中 执行postProcessMergedBeanDefinition方法,这里主要是为了合并bean的定义的。 其中 执行的类有主要以下3个 AutowiredAnnotataionBeanPostProcessor处理Autowired,Value注解 CommonAnnotationBeanPostProcessor处理Resource InitDestroyAnnotationBeanPostProcessor处理PostConstruct,PreDestroy protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class? beanType, String beanName) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof MergedBeanDefinitionPostProcessor) {MergedBeanDefinitionPostProcessor bdp (MergedBeanDefinitionPostProcessor) bp;bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);}}}/***spring通过此方法找出所有需要注入的字段同时做缓存* 这个接口下有很多的实现类最常见的就是* AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor* Post-process the given merged bean definition for the specified bean.* param beanDefinition the merged bean definition for the bean* param beanType the actual type of the managed bean instance* param beanName the name of the bean* see AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors*/void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class? beanType, String beanName); 2.2.1 CommonAnnotationBeanPostProcessor Overridepublic void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class? beanType, String beanName) {// 处理PostConstruct和PreDestroy注解super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);//找出beanType所有被Resource标记的字段和方法封装到InjectionMetadata中InjectionMetadata metadata findResourceMetadata(beanName, beanType, null);metadata.checkConfigMembers(beanDefinition);}/*** 解析Resource注解* param beanName* param clazz* param pvs* return*/private InjectionMetadata findResourceMetadata(String beanName, final Class? clazz, Nullable PropertyValues pvs) {// Fall back to class name as cache key, for backwards compatibility with custom callers.// 获取对应的bean名称作为缓存keyString cacheKey (StringUtils.hasLength(beanName) ? beanName : clazz.getName());// Quick check on the concurrent map first, with minimal locking.// 从缓存中获取注入元数据对象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对象放入injectionMetadataCache缓存中缓存key为beanName供后续方法从缓存中取出metadata buildResourceMetadata(clazz);this.injectionMetadataCache.put(cacheKey, metadata);}}}return metadata;}private InjectionMetadata buildResourceMetadata(final Class? clazz) {// 判断当前clazz是否是候选classif (!AnnotationUtils.isCandidateClass(clazz, resourceAnnotationTypes)) {return InjectionMetadata.EMPTY;}// 创建InjectedElement集合对象ListInjectionMetadata.InjectedElement elements new ArrayList();Class? targetClass clazz;do {final ListInjectionMetadata.InjectedElement currElements new ArrayList();// 查询是否有webService,ejb,Resource的属性注解但是不支持静态属性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 (ejbClass ! null field.isAnnotationPresent(ejbClass)) {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);}//如果不想注入某一类型对象 可以将其加入ignoredResourceTypes中if (!this.ignoredResourceTypes.contains(field.getType().getName())) {//字段会封装到ResourceElementcurrElements.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 (ejbClass ! null bridgedMethod.isAnnotationPresent(ejbClass)) {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);}2.2.2 InitDestroyAnnotationBeanPostProcessor public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class? beanType, String beanName) {// 调用方法获取生命周期元数据并保存LifecycleMetadata metadata findLifecycleMetadata(beanType);// 验证相关方法metadata.checkConfigMembers(beanDefinition);}private LifecycleMetadata findLifecycleMetadata(Class? clazz) {if (this.lifecycleMetadataCache null) {// Happens after deserialization, during destruction...// 在bean销毁过程中反序列化后调用return buildLifecycleMetadata(clazz);}// Quick check on the concurrent map first, with minimal locking.// 首先尝试从缓存中获取元数据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;}/*** 构造生命周期元数据解析带PostConstruct和PreDestroy注解的方法当其构造完成后会将元数据缓存到lifecycleMetadataCache集合中并返回* 此时就完成了相关方法初始化方法和销毁方法的扫描解析和缓存工作** param clazz* return*/private LifecycleMetadata buildLifecycleMetadata(final Class? clazz) {if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {return this.emptyLifecycleMetadata;}// 实例化后的回调方法PostConstructListLifecycleElement initMethods new ArrayList();// 销毁前的回调方法PreDestroyListLifecycleElement destroyMethods new ArrayList();// 获取正在处理的目标类Class? targetClass clazz;do {// 保存每一轮循环搜索到的相关方法final ListLifecycleElement currInitMethods new ArrayList();final ListLifecycleElement currDestroyMethods new ArrayList();// 反射获取当前类中的所有方法并依次对其调用第二个参数的lambda表达式ReflectionUtils.doWithLocalMethods(targetClass, method - {// 当前方法的注解中包含initAnnotationType注解时PostConstructif (this.initAnnotationType ! null method.isAnnotationPresent(this.initAnnotationType)) {// 如果有把它封装成LifecycleElement对象存储起来LifecycleElement element new LifecycleElement(method);// 将创建好的元素添加到集合中currInitMethods.add(element);if (logger.isTraceEnabled()) {logger.trace(Found init method on class [ clazz.getName() ]: method);}}// 当前方法的注解中包含destroyAnnotationType注解PreDestroyif (this.destroyAnnotationType ! null method.isAnnotationPresent(this.destroyAnnotationType)) {// 如果有把它封装成LifecycleElement对象存储起来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();}// 如果当前类存在父类且父类不为object基类则循环对父类进行处理while (targetClass ! null targetClass ! Object.class);// 有一个不为空就封装一个LifecycleMetadata对象否则就返回空的emptyLifecycleMetadatareturn (initMethods.isEmpty() destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :new LifecycleMetadata(clazz, initMethods, destroyMethods));}2.2.3 AutowiredAnnotationBeanPostProcessor /*** 处理合并的bean定义信息* 1、解析Autowired等注解然后转换* 2、把注解信息转换为InjectionMetadata然后缓存到上面的injectionMetadataCache里面* param beanDefinition the merged bean definition for the bean* param beanType the actual type of the managed bean instance* param beanName the name of the bean*/Overridepublic void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class? beanType, String beanName) {// 解析注解并缓存InjectionMetadata metadata findAutowiringMetadata(beanName, beanType, null);metadata.checkConfigMembers(beanDefinition);}/*** 方法名为查找到该bean的依赖注入元信息内部只要查找到了就会加入到缓存内下次没必要再重复查找了~* 它是一个模版方法真正做事的方法是buildAutowiringMetadata它复杂把标注有Autowired注解的属性转换为Metadata元数据信息从而消除注解的定义* 此处查找包括了字段依赖注入和方法依赖注入~~~* param beanName* param clazz* param pvs* return*/private InjectionMetadata findAutowiringMetadata(String beanName, Class? clazz, Nullable PropertyValues pvs) {// Fall back to class name as cache key, for backwards compatibility with custom callers.String cacheKey (StringUtils.hasLength(beanName) ? beanName : clazz.getName());// Quick check on the concurrent map first, with minimal locking.// 从缓存中获取该类的信息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 buildAutowiringMetadata(clazz);this.injectionMetadataCache.put(cacheKey, metadata);}}}return metadata;}/*** 去寻找有Autowired和Value注解的属性和方法也包括自定义的父类的封装成AutowiredMethodElement放入集合中* param clazz* return*/private InjectionMetadata buildAutowiringMetadata(final Class? clazz) {// 如果clazz是JDK中的类直接忽略因为不可能标注有这些标注if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {return InjectionMetadata.EMPTY;}ListInjectionMetadata.InjectedElement elements new ArrayList();Class? targetClass clazz;do {final ListInjectionMetadata.InjectedElement currElements new ArrayList();// 遍历类中的每个属性判断属性是否包含指定的属性(通过 findAutowiredAnnotation 方法)// 如果存在则保存这里注意属性保存的类型是 AutowiredFieldElementReflectionUtils.doWithLocalFields(targetClass, field - {MergedAnnotation? ann findAutowiredAnnotation(field);if (ann ! null) {//Autowired注解不支持静态方法if (Modifier.isStatic(field.getModifiers())) {if (logger.isInfoEnabled()) {logger.info(Autowired annotation is not supported on static fields: field);}return;}//查看是否是required的boolean required determineRequiredStatus(ann);currElements.add(new AutowiredFieldElement(field, required));}});// 遍历类中的每个方法判断属性是否包含指定的属性(通过 findAutowiredAnnotation 方法)// 如果存在则保存这里注意方法保存的类型是 AutowiredMethodElementReflectionUtils.doWithLocalMethods(targetClass, method - {Method bridgedMethod BridgeMethodResolver.findBridgedMethod(method);if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {return;}MergedAnnotation? ann findAutowiredAnnotation(bridgedMethod);if (ann ! null method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {if (Modifier.isStatic(method.getModifiers())) {if (logger.isInfoEnabled()) {logger.info(Autowired annotation is not supported on static methods: method);}return;}// 如果方法没有入参输出日志不做任何处理if (method.getParameterCount() 0) {if (logger.isInfoEnabled()) {logger.info(Autowired annotation should only be used on methods with parameters: method);}}boolean required determineRequiredStatus(ann);PropertyDescriptor pd BeanUtils.findPropertyForMethod(bridgedMethod, clazz);// AutowiredMethodElement里封装了一个PropertyDescriptor比字段多了一个参数currElements.add(new AutowiredMethodElement(method, required, pd));}});// 父类的都放在第一位所以父类是最先完成依赖注入的elements.addAll(0, currElements);targetClass targetClass.getSuperclass();}while (targetClass ! null targetClass ! Object.class);// InjectionMetadata就是对clazz和elements的一个包装而已return InjectionMetadata.forElements(elements, clazz);}2.3 populateBean() 该方法的核心流程主要就是填充属性 一部分代码是支持老的xml的注入的方式 一部分是支持新式的注解的方式例如像Resource,Autowired注解这一部分的关键代码就在于postProcessProperties()中 protected void populateBean(String beanName, RootBeanDefinition mbd, Nullable BeanWrapper bw) {// 如果beanWrapper为空if (bw null) {// 如果mbd有需要设置的属性if (mbd.hasPropertyValues()) {// 抛出bean创建异常throw new BeanCreationException(mbd.getResourceDescription(), beanName, Cannot apply property values to null instance);}else {// Skip property population phase for null instance.// 没有可填充的属性直接跳过return;}}// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the// state of the bean before properties are set. This can be used, for example,// to support styles of field injection.// 给任何实现了InstantiationAwareBeanPostProcessors的子类机会去修改bean的状态再设置属性之前可以被用来支持类型的字段注入// 否是synthetic。一般是指只有AOP相关的pointCut配置或者Advice配置才会将 synthetic设置为true// 如果mdb是不是syntheic且工厂拥有InstantiationAwareBeanPostProcessor// 这里可以写接口可以让所有类都不能依赖注入if (!mbd.isSynthetic() hasInstantiationAwareBeanPostProcessors()) {//遍历工厂中的BeanPostProcessor对象for (BeanPostProcessor bp : getBeanPostProcessors()) {//如果 bp 是 InstantiationAwareBeanPostProcessor 实例if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp (InstantiationAwareBeanPostProcessor) bp;// //postProcessAfterInstantiation一般用于设置属性if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {return;}}}}//PropertyValues包含以一个或多个PropertyValue对象的容器通常包括针对特定目标Bean的一次更新//如果mdb有PropertyValues就获取其PropertyValues//这个是程序员在 bd中 写入的属性rootBeanDefinition.getPropertyValues().add(type,男的);或者是XML中定义Bean的时候 加的PropertyValue标签PropertyValues pvs (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);// 获取 mbd 的 自动装配模式// 这里正常时用来依赖注入 以前xml方式配置的那种// bean idperson classcom.Person autowirebyName/beanint resolvedAutowireMode mbd.getResolvedAutowireMode();// 如果 自动装配模式 为 按名称自动装配bean属性 或者 按类型自动装配bean属性if (resolvedAutowireMode AUTOWIRE_BY_NAME || resolvedAutowireMode AUTOWIRE_BY_TYPE) {//MutablePropertyValuesPropertyValues接口的默认实现。允许对属性进行简单操作并提供构造函数来支持从映射 进行深度复制和构造MutablePropertyValues newPvs new MutablePropertyValues(pvs);// Add property values based on autowire by name if applicable.// 根据autotowire的名称(如适用)添加属性值if (resolvedAutowireMode AUTOWIRE_BY_NAME) {//通过bw的PropertyDescriptor属性名查找出对应的Bean对象将其添加到newPvs中autowireByName(beanName, mbd, bw, newPvs);}// Add property values based on autowire by type if applicable.// 根据自动装配的类型(如果适用)添加属性值if (resolvedAutowireMode AUTOWIRE_BY_TYPE) {//通过bw的PropertyDescriptor属性类型查找出对应的Bean对象将其添加到newPvs中autowireByType(beanName, mbd, bw, newPvs);}//让pvs重新引用newPvs,newPvs此时已经包含了pvs的属性值以及通过AUTOWIRE_BY_NAMEAUTOWIRE_BY_TYPE自动装配所得到的属性值pvs newPvs;}//这里是对非autowiring的属性进行依赖注入处理//工厂是否拥有InstiationAwareBeanPostProcessorboolean hasInstAwareBpps hasInstantiationAwareBeanPostProcessors();//mbd.getDependencyCheck()默认返回 DEPENDENCY_CHECK_NONE表示 不检查//是否需要依赖检查boolean needsDepCheck (mbd.getDependencyCheck() ! AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);//经过筛选的PropertyDesciptor数组,存放着排除忽略的依赖项或忽略项上的定义的属性PropertyDescriptor[] filteredPds null;//如果工厂拥有InstiationAwareBeanPostProcessor,那么处理对应的流程主要是对几个注解的赋值工作包含的两个关键子类是CommonAnnoationBeanPostProcessor,AutowiredAnnotationBeanPostProcessorif (hasInstAwareBpps) {//如果pvs为nullif (pvs null) {//尝试获取mbd的PropertyValuespvs mbd.getPropertyValues();}//遍历工厂内的所有后置处理器for (BeanPostProcessor bp : getBeanPostProcessors()) {//如果 bp 是 InstantiationAwareBeanPostProcessor 的实例if (bp instanceof InstantiationAwareBeanPostProcessor) {//将bp 强转成 InstantiationAwareBeanPostProcessor 对象InstantiationAwareBeanPostProcessor ibp (InstantiationAwareBeanPostProcessor) bp;//postProcessProperties:在工厂将给定的属性值应用到给定Bean之前对它们进行后处理不需要任何属性扫描符。// 让ibp对pvs增加对bw的Bean对象的propertyValue或编辑pvs的proertyValue//依赖注入过程Autowired、Resource、Value等注解的注入PropertyValues pvsToUse ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);//如果pvs为nullif (pvsToUse null) {//如果filteredPds为nullif (filteredPds null) {//mbd.allowCaching:是否允许缓存默认时允许的。缓存除了可以提高效率以外还可以保证在并发的情况下返回的PropertyDesciptor[]永远都是同一份//从bw提取一组经过筛选的PropertyDesciptor,排除忽略的依赖项或忽略项上的定义的属性filteredPds filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}// 老版本用这个完成依赖注入过程Autowired的支持pvsToUse ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);//如果pvsToUse为null将终止该方法精致以跳过属性填充if (pvsToUse null) {return;}}//让pvs引用pvsToUsepvs pvsToUse;}}}//如果需要依赖检查if (needsDepCheck) {//如果filteredPds为nullif (filteredPds null) {//从bw提取一组经过筛选的PropertyDesciptor,排除忽略的依赖项或忽略项上的定义的属性filteredPds filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}//检查依赖项主要检查pd的setter方法需要赋值时,pvs中有没有满足其pd的需求的属性值可供其赋值checkDependencies(beanName, mbd, filteredPds, pvs);}//这个方法建议不看是老版本用property namexxx valuexxx/这种标签才会进来的。//标签做依赖注入的代码实现里面超鸡儿复杂。现在都用注解了可以不看if (pvs ! null) {//应用给定的属性值解决任何在这个bean工厂运行时其他bean的引用。必须使用深拷贝所以我们 不会永久地修改这个属性applyPropertyValues(beanName, mbd, bw, pvs);}}2.3.1 postProcessProperties() 这个其实再上面的applyMergedBeanDefinitionPostProcessors()方法中已经讲过了 上面那个是会先提前读取 然后放入对应的缓存中 再这边是直接 读取缓存的。然后进行注入采用反射的方式进行。这里只讲注入的代码段 AutowiredAnnotationBeanPostProcessor AutoWired public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {InjectionMetadata metadata findAutowiringMetadata(beanName, bean.getClass(), pvs);try {metadata.inject(bean, beanName, pvs);}catch (BeanCreationException ex) {throw ex;}catch (Throwable ex) {throw new BeanCreationException(beanName, Injection of autowired dependencies failed, ex);}return pvs;}private InjectionMetadata findAutowiringMetadata(String beanName, Class? clazz, Nullable PropertyValues pvs) {// Fall back to class name as cache key, for backwards compatibility with custom callers.String cacheKey (StringUtils.hasLength(beanName) ? beanName : clazz.getName());// Quick check on the concurrent map first, with minimal locking.//此处缓存中有数据直接就返回了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 buildAutowiringMetadata(clazz);this.injectionMetadataCache.put(cacheKey, metadata);}}}return metadata;public void inject(Object target, Nullable String beanName, Nullable PropertyValues pvs) throws Throwable {CollectionInjectedElement checkedElements this.checkedElements;CollectionInjectedElement elementsToIterate (checkedElements ! null ? checkedElements : this.injectedElements);if (!elementsToIterate.isEmpty()) {//循环每个带有Atowared注解的参数或者方法依次通过反射赋值for (InjectedElement element : elementsToIterate) {if (logger.isTraceEnabled()) {logger.trace(Processing injected element of bean beanName : element);}//反射核心方法处理参数或者方法点击element.inject(target, beanName, pvs);}}}element.inject(target, beanName, pvs);方法参数赋值Overrideprotected void inject(Object bean, Nullable String beanName, Nullable PropertyValues pvs) throws Throwable {Field field (Field) this.member;Object value;if (this.cached) {value resolvedCachedArgument(beanName, this.cachedFieldValue);}else {DependencyDescriptor desc new DependencyDescriptor(field, this.required);desc.setContainingClass(bean.getClass());SetString autowiredBeanNames new LinkedHashSet(1);Assert.state(beanFactory ! null, No BeanFactory available);TypeConverter typeConverter beanFactory.getTypeConverter();try {//这里会触发依赖注入属性的getBean操作前几篇分析过此处省略value beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);}catch (BeansException ex) {throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);}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) beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {this.cachedFieldValue new ShortcutDependencyDescriptor(desc, autowiredBeanName, field.getType());}}}else {this.cachedFieldValue null;}this.cached true;}}}if (value ! null) {ReflectionUtils.makeAccessible(field);//最终通过反射赋值参数如下。field.set(bean, value);}}}// 方法赋值Overrideprotected void inject(Object bean, Nullable String beanName, Nullable PropertyValues pvs) throws Throwable {if (checkPropertySkipping(pvs)) {return;}Method method (Method) this.member;Object[] arguments;if (this.cached) {// Shortcut for avoiding synchronization...arguments resolveCachedArguments(beanName);}else {int argumentCount method.getParameterCount();arguments new Object[argumentCount];DependencyDescriptor[] descriptors new DependencyDescriptor[argumentCount];SetString autowiredBeans new LinkedHashSet(argumentCount);Assert.state(beanFactory ! null, No BeanFactory available);TypeConverter typeConverter beanFactory.getTypeConverter();for (int i 0; i arguments.length; i) {MethodParameter methodParam new MethodParameter(method, i);DependencyDescriptor currDesc new DependencyDescriptor(methodParam, this.required);currDesc.setContainingClass(bean.getClass());descriptors[i] currDesc;try {Object arg beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);if (arg null !this.required) {arguments null;break;}arguments[i] arg;}catch (BeansException ex) {throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);}}synchronized (this) {if (!this.cached) {if (arguments ! null) {DependencyDescriptor[] cachedMethodArguments Arrays.copyOf(descriptors, arguments.length);registerDependentBeans(beanName, autowiredBeans);if (autowiredBeans.size() argumentCount) {IteratorString it autowiredBeans.iterator();Class?[] paramTypes method.getParameterTypes();for (int i 0; i paramTypes.length; i) {String autowiredBeanName it.next();if (beanFactory.containsBean(autowiredBeanName) beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {cachedMethodArguments[i] new ShortcutDependencyDescriptor(descriptors[i], autowiredBeanName, paramTypes[i]);}}}this.cachedMethodArguments cachedMethodArguments;}else {this.cachedMethodArguments null;}this.cached true;}}}if (arguments ! null) {try {ReflectionUtils.makeAccessible(method);method.invoke(bean, arguments);//方法执行}catch (InvocationTargetException ex) {throw ex.getTargetException();}}}2.3.2 循环依赖问题 在填充属性的时候会涉及到循环依赖的问题 导致循环依赖原因 由构造函数造成的循环依赖通过setter方法注入且是多例模式下可能导致内存溢出通过setter方法注入且是单例模式下可能导致内存溢出 解决方式 在Spring中只有第3种方式的循环依赖问题被解决其他两种会报异常。 第1种构造方法注入的情况下在new对象的时候就会堵塞住了其实也就是”先有鸡还是先有蛋“的历史难题。 第2种setter方法多例的情况下每一次getBean()时都会产生一个新的Bean如此反复下去就会有无穷无尽的Bean产生了最终就会导致OOM问题的出现。 三级缓存 public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {1.singletonobject 单例池 存放已完成初始化的bean//一级缓存(单例池经过完成生命周期的对象会放入其中)private final MapString, Object singletonObjects new ConcurrentHashMap(256);2.存放未完成初始化的但是已经实例化的bean//二级缓存(刚实例化还未初始化的原始对象会放入其中)private final MapString, Object earlySingletonObjects new HashMap(16);3.存放某个bean的beanfactory//三级缓存(存放创建某个对象的工厂)private final MapString, ObjectFactory? singletonFactories new HashMap(16);。。。。。。。。 }2.4 initializeBean()概览 到此时bean 已完成了如下两个重要工作 调用 createBeanInstance() 方法完成 bean 的实例化工作 调用 populateBean() 方法完成 bean 的属性填充注入工作 接下来就是进行初始化工作了先上流程图在看细节 /*** 初始化给定的bean实例应用工厂回调以及init方法和BeanPostProcessors** Initialize the given bean instance, applying factory callbacks* as well as init methods and bean post processors.* pCalled from {link #createBean} for traditionally defined beans,* and from {link #initializeBean} for existing bean instances.* param beanName the bean name in the factory (for debugging purposes)* param bean the new bean instance we may need to initialize* param mbd the bean definition that the bean was created with* (can also be {code null}, if given an existing bean instance)* return the initialized bean instance (potentially wrapped)* see BeanNameAware* see BeanClassLoaderAware* see BeanFactoryAware* see #applyBeanPostProcessorsBeforeInitialization* see #invokeInitMethods* see #applyBeanPostProcessorsAfterInitialization*/ protected Object initializeBean(String beanName, Object bean, Nullable RootBeanDefinition mbd) {// 如果安全管理器不为空if (System.getSecurityManager() ! null) {// 以特权的方式执行回调bean中的Aware接口方法AccessController.doPrivileged((PrivilegedActionObject) () - {invokeAwareMethods(beanName, bean);return null;}, getAccessControlContext());}else {// Aware接口处理器调用BeanNameAware、BeanClassLoaderAware、beanFactoryAwareinvokeAwareMethods(beanName, bean);}Object wrappedBean bean;//如果mdb为null || mbd不是synthetic。一般是指只有AOP相关的prointCut配置或者Advice配置才会将 synthetic设置为trueif (mbd null || !mbd.isSynthetic()) {// 将BeanPostProcessors应用到给定的现有Bean实例调用它们的postProcessBeforeInitialization初始化方法。// 返回的Bean实例可能是原始Bean包装器wrappedBean applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {//调用初始化方法先调用bean的InitializingBean接口方法后调用bean的自定义初始化方法invokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {//捕捉调用初始化方法时抛出的异常重新抛出Bean创建异常调用初始化方法失败throw new BeanCreationException((mbd ! null ? mbd.getResourceDescription() : null),beanName, Invocation of init method failed, ex);}//如果mbd为null || mbd不是syntheticif (mbd null || !mbd.isSynthetic()) {// 将BeanPostProcessors应用到给定的现有Bean实例调用它们的postProcessAfterInitialization方法。// 返回的Bean实例可能是原始Bean包装器wrappedBean applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}//返回包装后的Beanreturn wrappedBean;}2.4.1 invokeAwareMethods() 方法 实现 Aware 接口用于让 bean 能拥有某些额外的感知能力 如果 bean 实现了 BeanNameAware 接口则将 beanName 设置进去 如果 bean 实现了 BeanClassLoaderAware 接口则将 ClassLoader 设置进去 如果 bean 实现了 BeanFactoryAware 接口则将 beanFactory 设置进去 private void invokeAwareMethods(String beanName, Object bean) {//如果 bean 是 Aware 实例if (bean instanceof Aware) {//如果bean是BeanNameAware实例if (bean instanceof BeanNameAware) {//调用 bean 的setBeanName方法((BeanNameAware) bean).setBeanName(beanName);}//如果bean是 BeanClassLoaderAware 实例if (bean instanceof BeanClassLoaderAware) {//获取此工厂的类加载器以加载Bean类(即使无法使用系统ClassLoader,也只能为null)ClassLoader bcl getBeanClassLoader();if (bcl ! null) {//调用 bean 的 setBeanClassLoader 方法((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);}}//如果bean是 BeanFactoryAware 实例if (bean instanceof BeanFactoryAware) {// //调用 bean 的 setBeanFactory 方法((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}}2.4.2 applyBeanPostProcessorsBeforeInitialization() 方法重点 在 bean 初始化之前调用可以改变 bean 的一些属性 public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)throws BeansException {//初始化返回结果为existingBeanObject result existingBean;//遍历 该工厂创建的bean的BeanPostProcessors列表for (BeanPostProcessor processor : getBeanPostProcessors()) {// postProcessBeforeInitialization在任何Bean初始化回调之前(如初始化Bean的afterPropertiesSet或自定义的init方法)// 将此BeanPostProcessor 应用到给定的新Bean实例。Bean已经填充了属性值。返回的Bean实例可能时原始Bean的包装器。// 默认实现按原样返回给定的 BeanObject current processor.postProcessBeforeInitialization(result, beanName);// 如果 current为nullif (current null) {//直接返回result中断其后续的BeanPostProcessor处理return result;}//让result引用processor的返回结果,使其经过所有BeanPostProcess对象的后置处理的层层包装result current;}//返回经过所有BeanPostProcess对象的后置处理的层层包装后的resultreturn result;}2.4.3 invokeInitMethods() 方法重点 Spring为 bean 提供了两种初始化的方式第一种是实现 InitializingBean 接口调用 afterPropertiesSet() 方法来完成初始化 第二种通过反射调用 init-method 指定的方法相比效率相对低。但是 init-method 方式消除了对 Spring 的依赖 如果调用 afterPropertiesSet() 方法时出错那么就不会调用 init-method 指定的方法了 protected void invokeInitMethods(String beanName, Object bean, Nullable RootBeanDefinition mbd)throws Throwable {// InitializingBean:当Bean的所有属性都被BeanFactory设置好后Bean需要执行相应的接口例如执行自定义初始化或者仅仅是检查所有强制属性是否已经设置好。// bean是InitializingBean实例标记boolean isInitializingBean (bean instanceof InitializingBean);// isExternallyManagedInitMethod是否外部受管理的Init方法名// 如果bean是InitializingBean实例(mdb为null||afterPropertiesSet不是外部受管理的Init方法名)if (isInitializingBean (mbd null || !mbd.isExternallyManagedInitMethod(afterPropertiesSet))) {// 如果是日志级别为跟踪模式if (logger.isTraceEnabled()) {logger.trace(Invoking afterPropertiesSet() on bean with name beanName );}// 如果安全管理器不为nullif (System.getSecurityManager() ! null) {try {// 以特权方式调用 bean的 afterPropertiesSet 方法AccessController.doPrivileged((PrivilegedExceptionActionObject) () - {((InitializingBean) bean).afterPropertiesSet();return null;}, getAccessControlContext());}catch (PrivilegedActionException pae) {throw pae.getException();}}else {// 调用bean的afterPropertiesSet方法((InitializingBean) bean).afterPropertiesSet();}}// 如果mbd不为nullbean不是NullBean类if (mbd ! null bean.getClass() ! NullBean.class) {// 获取mbd指定的初始化方法名String initMethodName mbd.getInitMethodName();// 如果initMethodName不为null(bean不是InitializingBean实例afterPropertiesSet是初始化方法名// initMethodName不是外部受管理的Init方法名if (StringUtils.hasLength(initMethodName) !(isInitializingBean afterPropertiesSet.equals(initMethodName)) !mbd.isExternallyManagedInitMethod(initMethodName)) {// 在bean上调用指定的自定义init方法invokeCustomInitMethod(beanName, bean, mbd);}}}protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd)throws Throwable {// 获取初始化方法名称String initMethodName mbd.getInitMethodName();Assert.state(initMethodName ! null, No init method set);// 获取初始化方法Method initMethod (mbd.isNonPublicAccessAllowed() ?BeanUtils.findMethod(bean.getClass(), initMethodName) :ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));if (initMethod null) {if (mbd.isEnforceInitMethod()) {throw new BeanDefinitionValidationException(Could not find an init method named initMethodName on bean with name beanName );}else {if (logger.isTraceEnabled()) {logger.trace(No default init method named initMethodName found on bean with name beanName );}// Ignore non-existent default lifecycle methods.return;}}if (logger.isTraceEnabled()) {logger.trace(Invoking init method initMethodName on bean with name beanName );}Method methodToInvoke ClassUtils.getInterfaceMethodIfPossible(initMethod);if (System.getSecurityManager() ! null) {AccessController.doPrivileged((PrivilegedActionObject) () - {ReflectionUtils.makeAccessible(methodToInvoke);return null;});try {AccessController.doPrivileged((PrivilegedExceptionActionObject)() - methodToInvoke.invoke(bean), getAccessControlContext());}catch (PrivilegedActionException pae) {InvocationTargetException ex (InvocationTargetException) pae.getException();throw ex.getTargetException();}}else {try {ReflectionUtils.makeAccessible(methodToInvoke);// 反射执行methodToInvoke.invoke(bean);}catch (InvocationTargetException ex) {throw ex.getTargetException();}}}2.4.4 applyBeanPostProcessorsAfterInitialization() 方法重点 postProcessAfterInitialization() 方法是 BeanPostProcessor 接口提供的方法可以看到它是在 bean 初始化之后调用的这时的 bean 已完成了实例化属性填充注入初始化的工作可以认为是一个完整的 bean 已在 spring 容器中了这个地方也是产生代理对象的地方 也就是AOP的入口 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {//初始化结果对象为result默认引用existingBeanObject result existingBean;//遍历该工厂创建的bean的BeanPostProcessors列表for (BeanPostProcessor processor : getBeanPostProcessors()) {//回调BeanPostProcessor#postProcessAfterInitialization来对现有的bean实例进行包装Object current processor.postProcessAfterInitialization(result, beanName);//一般processor对不感兴趣的bean会回调直接返回result使其能继续回调后续的BeanPostProcessor// 但有些processor会返回null来中断其后续的BeanPostProcessor// 如果current为nullif (current null) {//直接返回result中断其后续的BeanPostProcessor处理return result;}//让result引用processor的返回结果,使其经过所有BeanPostProcess对象的后置处理的层层包装result current;}//返回经过所有BeanPostProcess对象的后置处理的层层包装后的resultreturn result;}2.4.5 registerDisposableBeanIfNecessary() /*** 将给定Bean添加到该工厂中的可丢弃Bean列表中注册器可丢弃Bean接口和/或在工厂关闭时调用给定销毁方法如果适用。只适用单例** Add the given bean to the list of disposable beans in this factory,* registering its DisposableBean interface and/or the given destroy method* to be called on factory shutdown (if applicable). Only applies to singletons.* param beanName the name of the bean* param bean the bean instance* param mbd the bean definition for the bean* see RootBeanDefinition#isSingleton* see RootBeanDefinition#getDependsOn* see #registerDisposableBean* see #registerDependentBean*/protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {// 如果有安全管理器器获取其访问控制上下文AccessControlContext acc (System.getSecurityManager() ! null ? getAccessControlContext() : null);// 如果mbd不是Prototype作用域 bean在关闭时需要销毁if (!mbd.isPrototype() requiresDestruction(bean, mbd)) {// 如果mbd是单例作用域if (mbd.isSingleton()) {// Register a DisposableBean implementation that performs all destruction// work for the given bean: DestructionAwareBeanPostProcessors,// DisposableBean interface, custom destroy method.// 注册一个一次性Bean实现来执行给定Bean的销毁工作DestructionAwareBeanPostProcessors 一次性Bean接口自定义销毁方法。// DisposableBeanAdapter实际一次性Bean和可运行接口适配器对给定Bean实例执行各种销毁步骤// 构建Bean对应的DisposableBeanAdapter对象与beanName绑定到 注册中心的一次性Bean列表中registerDisposableBean(beanName,new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));}else {// A bean with a custom scope...// 具有自定已作用域的Bean// 获取mdb的作用域Scope scope this.scopes.get(mbd.getScope());// 如果作用域为nullif (scope null) {// 非法状态异常无作用登记为作用名称mbd.getScopethrow new IllegalStateException(No Scope registered for scope name mbd.getScope() );}// 注册一个回调在销毁作用域中将构建Bean对应的DisposableBeanAdapter对象指定(或者在销毁整个作用域时执行// 如果作用域没有销毁单个对象而是全部终止)scope.registerDestructionCallback(beanName,new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));}}}2.4.6 补充Spring中bean初始化的方式 一、ContextRefreshedEvent事件 ContextRefreshedEvent是Spring容器初始化完成后调用的事件。 ContextRefreshedEvent的父类是ApplicationContextEvent是一个事件。所以我们通过ApplicationListener来实现 Component public class PersonAfterListener implements ApplicationListenerContextRefreshedEvent {Autowiredprivate Person person;Overridepublic void onApplicationEvent(ContextRefreshedEvent event) {person.run(ContextRefreshedEvent);} } 二、PostConstruct 注解 PostConstruct注解修饰的方式是在spring容器启动时运行的。优先级大于ContextRefreshedEvent事件。 Component public class PersonAfterPostConstruct {Autowiredprivate Person person;PostConstructpublic void postConstruct(){person.run(PostConstruct);} }三、InitializingBean InitializingBean是spring容器在启动并初始化好内部示例后调用的用来最终为总体bean添加最后属性和操作。 Component public class PersonAfterInitializingBean implements InitializingBean {Autowiredprivate Person person;Overridepublic void afterPropertiesSet() throws Exception {person.run(InitializingBean);} } 四、init-method方法 这种方法有一定的局限性并且可能会覆盖曾经的init操作需要慎用。 Bean在加载到Spring容器中时需要先将Bean的定义信息抽象为BeanDefinition其中有一个属性init-method代表将来Bean初始化时要调用的方法。 我们通过BeanFactoryPostProcessor来注入init-method方法并且该方法必须是没有参数的。 import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.stereotype.Component;Component public class PersonAfterInit implements BeanFactoryPostProcessor {Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {BeanDefinition person beanFactory.getBeanDefinition(person);person.setInitMethodName(run);} } 五 、实现 SmartInitializingSingleton 接口 SmartInitializingSingleton是Bean容器在初始化所有非懒加载的单例Bean后调用的方法。 Component public class PersonAfterSmartInitializingSingleton implements SmartInitializingSingleton {Autowiredprivate Person person;Overridepublic void afterSingletonsInstantiated() {person.run(SmartInitializingSingleton);} }六、CommandLineRunner仅限Spring Boot CommandLineRunner 是一个Spring boot 接口在应用初始化后执行且仅会执行一次。可以用来打印项目中配置文件的参数方便排查问题。 Component public class PersonAfterCommandLineRunner implements CommandLineRunner {Autowiredprivate Person person;Overridepublic void run(String... args) throws Exception {person.run(CommandLineRunner);} }
文章转载自:
http://www.morning.lmqw.cn.gov.cn.lmqw.cn
http://www.morning.rrgqq.cn.gov.cn.rrgqq.cn
http://www.morning.rwlns.cn.gov.cn.rwlns.cn
http://www.morning.kxsnp.cn.gov.cn.kxsnp.cn
http://www.morning.wktbz.cn.gov.cn.wktbz.cn
http://www.morning.xkqjw.cn.gov.cn.xkqjw.cn
http://www.morning.dhqyh.cn.gov.cn.dhqyh.cn
http://www.morning.tqsmg.cn.gov.cn.tqsmg.cn
http://www.morning.hhqjf.cn.gov.cn.hhqjf.cn
http://www.morning.mlnzx.cn.gov.cn.mlnzx.cn
http://www.morning.tsqrc.cn.gov.cn.tsqrc.cn
http://www.morning.hwbf.cn.gov.cn.hwbf.cn
http://www.morning.clyhq.cn.gov.cn.clyhq.cn
http://www.morning.lbqt.cn.gov.cn.lbqt.cn
http://www.morning.ltrms.cn.gov.cn.ltrms.cn
http://www.morning.jbxmb.cn.gov.cn.jbxmb.cn
http://www.morning.wschl.cn.gov.cn.wschl.cn
http://www.morning.xhklb.cn.gov.cn.xhklb.cn
http://www.morning.qhydkj.com.gov.cn.qhydkj.com
http://www.morning.synkr.cn.gov.cn.synkr.cn
http://www.morning.dzdtj.cn.gov.cn.dzdtj.cn
http://www.morning.kljhr.cn.gov.cn.kljhr.cn
http://www.morning.tbnn.cn.gov.cn.tbnn.cn
http://www.morning.grpbt.cn.gov.cn.grpbt.cn
http://www.morning.pqbkk.cn.gov.cn.pqbkk.cn
http://www.morning.fdlyh.cn.gov.cn.fdlyh.cn
http://www.morning.jzfxk.cn.gov.cn.jzfxk.cn
http://www.morning.nzms.cn.gov.cn.nzms.cn
http://www.morning.djwpd.cn.gov.cn.djwpd.cn
http://www.morning.dygsz.cn.gov.cn.dygsz.cn
http://www.morning.wmhqd.cn.gov.cn.wmhqd.cn
http://www.morning.jpqmq.cn.gov.cn.jpqmq.cn
http://www.morning.cyfsl.cn.gov.cn.cyfsl.cn
http://www.morning.cyfsl.cn.gov.cn.cyfsl.cn
http://www.morning.qtkdn.cn.gov.cn.qtkdn.cn
http://www.morning.ssgqc.cn.gov.cn.ssgqc.cn
http://www.morning.bcdqf.cn.gov.cn.bcdqf.cn
http://www.morning.tpwrm.cn.gov.cn.tpwrm.cn
http://www.morning.mbfkt.cn.gov.cn.mbfkt.cn
http://www.morning.knrgb.cn.gov.cn.knrgb.cn
http://www.morning.bjjrtcsl.com.gov.cn.bjjrtcsl.com
http://www.morning.dcmnl.cn.gov.cn.dcmnl.cn
http://www.morning.rfgkf.cn.gov.cn.rfgkf.cn
http://www.morning.gdpai.com.cn.gov.cn.gdpai.com.cn
http://www.morning.srgbr.cn.gov.cn.srgbr.cn
http://www.morning.hxlch.cn.gov.cn.hxlch.cn
http://www.morning.jnbsx.cn.gov.cn.jnbsx.cn
http://www.morning.rkfh.cn.gov.cn.rkfh.cn
http://www.morning.yybcx.cn.gov.cn.yybcx.cn
http://www.morning.tpnch.cn.gov.cn.tpnch.cn
http://www.morning.cwyfs.cn.gov.cn.cwyfs.cn
http://www.morning.vvdifactory.com.gov.cn.vvdifactory.com
http://www.morning.rdtq.cn.gov.cn.rdtq.cn
http://www.morning.qnbsx.cn.gov.cn.qnbsx.cn
http://www.morning.gcszn.cn.gov.cn.gcszn.cn
http://www.morning.lxmks.cn.gov.cn.lxmks.cn
http://www.morning.bzcjx.cn.gov.cn.bzcjx.cn
http://www.morning.cdrzw.cn.gov.cn.cdrzw.cn
http://www.morning.xsqbx.cn.gov.cn.xsqbx.cn
http://www.morning.qbfkz.cn.gov.cn.qbfkz.cn
http://www.morning.fnrkh.cn.gov.cn.fnrkh.cn
http://www.morning.klyzg.cn.gov.cn.klyzg.cn
http://www.morning.yggwn.cn.gov.cn.yggwn.cn
http://www.morning.nqrlz.cn.gov.cn.nqrlz.cn
http://www.morning.hhzdj.cn.gov.cn.hhzdj.cn
http://www.morning.fflnw.cn.gov.cn.fflnw.cn
http://www.morning.dnmwl.cn.gov.cn.dnmwl.cn
http://www.morning.rwlsr.cn.gov.cn.rwlsr.cn
http://www.morning.frnjm.cn.gov.cn.frnjm.cn
http://www.morning.gbnsq.cn.gov.cn.gbnsq.cn
http://www.morning.jnptt.cn.gov.cn.jnptt.cn
http://www.morning.tnrdz.cn.gov.cn.tnrdz.cn
http://www.morning.psxfg.cn.gov.cn.psxfg.cn
http://www.morning.gjlml.cn.gov.cn.gjlml.cn
http://www.morning.gqtxz.cn.gov.cn.gqtxz.cn
http://www.morning.rnmdp.cn.gov.cn.rnmdp.cn
http://www.morning.wptdg.cn.gov.cn.wptdg.cn
http://www.morning.hlhqs.cn.gov.cn.hlhqs.cn
http://www.morning.rrxnz.cn.gov.cn.rrxnz.cn
http://www.morning.rlfr.cn.gov.cn.rlfr.cn
http://www.tj-hxxt.cn/news/251343.html

相关文章:

  • 装饰网站建设优惠套餐wordpress创意主题
  • 四川网站排名wordpress 广告
  • 苏州网站快速排名优化长春互联网公司排名
  • 好用的网站后台管理系统重庆建网站要多少钱
  • 网站架构的重要性建设商城网站
  • 邹平建设网站设计师网站十大网站
  • 网站开发设计实训总结网站开发与网站设计区别
  • 罗湖网站设计开发企业官网建站
  • 搞笑图片网站源码公司页面网站设计模板
  • 网页设计与制作的意思南通优化网站价格
  • 影楼网站源码dedecms 网站安全设置
  • 河南建设通网站如何免费制作和开发自己的小程序
  • seo网站沙盒期jquery 单页网站
  • 网站开发交互原型标注图免费手机网站源码
  • 网站必须做商标么做网站的怎么挣钱
  • 网站建设 要维护么网站开发部门工资入什么科目
  • dede网站名称不能中文重庆房地产网站建设
  • 相亲网站建设不同域名一样的网站
  • 网站分析怎么做自学设计软件的免费网站
  • 中山市城乡和住房建设局网站WordPress怎么导入大数据库
  • 遵义网站设计微信微网站开发百度云
  • 表格布局网站域名注册商有哪些
  • wap网站在线生成可信网站代码
  • 小程序转换成网页百度快照优化推广
  • 做网站的项目介绍wordpress插件 二次开放
  • 网站搭建费用明细沈阳关键词优化报价
  • 朝阳网站建设固原地网站seo
  • 会展相关网站建设网站备案icp备案
  • 红酒网站建设模板栾城住房和城乡建设局网站
  • jsp网站开发详解 pdfps自学网