zoukankan      html  css  js  c++  java
  • spring源码学习之bean的加载(三)

      接着二中的继续写,那个都超过1000行了,哈,需要重新写一个,要不太长了,我都看不下去了

    7.4 初始化bean

    doCreateBean函数中有这样一行代码:这行代码中initializeBean函数就是初始化bean的逻辑
    exposedObject = initializeBean(beanName, exposedObject, mbd);

    这个方法在org.springframework.beans.factory.support包下AbstractAutowireCapableBeanFactory类下

     1 /**
     2  * Initialize the given bean instance, applying factory callbacks
     3  * as well as init methods and bean post processors.
     4  * <p>Called from {@link #createBean} for traditionally defined beans,
     5  * and from {@link #initializeBean} for existing bean instances.
     6  * @param beanName the bean name in the factory (for debugging purposes)
     7  * @param bean the new bean instance we may need to initialize
     8  * @param mbd the bean definition that the bean was created with
     9  * (can also be {@code null}, if given an existing bean instance)
    10  * @return the initialized bean instance (potentially wrapped)
    11  * @see BeanNameAware
    12  * @see BeanClassLoaderAware
    13  * @see BeanFactoryAware
    14  * @see #applyBeanPostProcessorsBeforeInitialization
    15  * @see #invokeInitMethods
    16  * @see #applyBeanPostProcessorsAfterInitialization
    17  */
    18 protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    19     if (System.getSecurityManager() != null) {
    20         AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    21             invokeAwareMethods(beanName, bean);
    22             return null;
    23         }, getAccessControlContext());
    24     }
    25     else {
    26         // 对特殊的bean处理:Aware、BeanClassLoader、BeanFactoryAware
    27         invokeAwareMethods(beanName, bean);
    28     }
    29 
    30     Object wrappedBean = bean;
    31     if (mbd == null || !mbd.isSynthetic()) {
    32         // 应用后处理器
    33         wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    34     }
    35 
    36     try {
    37         // 激活用户自定义的init方法
    38         invokeInitMethods(beanName, wrappedBean, mbd);
    39     }
    40     catch (Throwable ex) {
    41         throw new BeanCreationException(
    42                 (mbd != null ? mbd.getResourceDescription() : null),
    43                 beanName, "Invocation of init method failed", ex);
    44     }
    45     if (mbd == null || !mbd.isSynthetic()) {
    46         // 后处理器应用
    47         wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    48     }
    49 
    50     return wrappedBean;
    51 }

    虽说此函数的目的主要是进行客户设定的初始化方法的调用,但是除此之外还有其他必要的工作

    (1)激活Aware方法
    理解一下Aware的使用,spring中提供了一些Aware接口,比如好多org.springframework.beans.factory,这个包下好多啊,实现这些Aware接口的bean被初始化之后
    可以取得一些相应的资源,例如,实现BeanFactoryAware的bean在初始化后,spring容器会注入BeanFactory的实例,来看一下Aware的使用

     1 // 定义普通的bean
     2 public class Hello{
     3     public void say(){
     4         System.out.println("hello");
     5     }
     6 }
     7 
     8 // 定义BeanFactoryAware类型的bean
     9 public class Test implements BeanFactoryAware {
    10     private BeanFactory beanFactory;
    11     
    12     // 声明bean的时候spring会自动注入BeanFactory
    13     @override
    14     public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    15         this.beanFactory = beanFactory;
    16     }
    17     
    18     public void testAware(){
    19         Hello hello = (Hello) beanFactory.getBean("hello");
    20         hello.say();
    21     }
    22 }

    基本上就是这样使用的,看一下 源码:
    这个方法在org.springframework.beans.factory.support包下AbstractAutowireCapableBeanFactory类下

     1 private void invokeAwareMethods(final String beanName, final Object bean) {
     2     if (bean instanceof Aware) {
     3         if (bean instanceof BeanNameAware) {
     4             ((BeanNameAware) bean).setBeanName(beanName);
     5         }
     6         if (bean instanceof BeanClassLoaderAware) {
     7             ClassLoader bcl = getBeanClassLoader();
     8             if (bcl != null) {
     9                 ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
    10             }
    11         }
    12         if (bean instanceof BeanFactoryAware) {
    13             ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
    14         }
    15     }
    16 }

    (2)处理器的应用

    BeanPostProcessor是spring开放式架构中必不可少的亮点,给用户充足的权限去更改或者扩展spring,除了BeanPostProcessor,还有很多PostProcessor,
    当然大部分都是以此为基础,继承组BeanPostProcessor,BeanPostProcessor的使用位置就是这里,在调用客户自定义初始方法前以及调用自定义初始方法后
    分别会调用BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization,使用户根据自己的需求进行自己处理
    这个方法在org.springframework.beans.factory.support包下AbstractAutowireCapableBeanFactory类下

     1 @Override
     2 public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
     3         throws BeansException {
     4 
     5     Object result = existingBean;
     6     for (BeanPostProcessor processor : getBeanPostProcessors()) {
     7         Object current = processor.postProcessBeforeInitialization(result, beanName);
     8         if (current == null) {
     9             return result;
    10         }
    11         result = current;
    12     }
    13     return result;
    14 }
    15 
    16 @Override
    17 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    18         throws BeansException {
    19 
    20     Object result = existingBean;
    21     for (BeanPostProcessor processor : getBeanPostProcessors()) {
    22         Object current = processor.postProcessAfterInitialization(result, beanName);
    23         if (current == null) {
    24             return result;
    25         }
    26         result = current;
    27     }
    28     return result;
    29 }

    (3)激活自定义的init方法
    客户定制的初始化方法除了我们熟知的使用init-method配置外,还要使用自定义bean实现initializeBean接口,并在afterPropertiesSet中实现自己的初始化逻辑
    init-method与afterPropertiesSet都是在初始化bean时执行,指定顺序是afterPropertiesSet先执行,init-method再执行

    在invokeInitMethods方法中实现了这部分处理逻辑

     1 /**
     2  * Give a bean a chance to react now all its properties are set,
     3  * and a chance to know about its owning bean factory (this object).
     4  * This means checking whether the bean implements InitializingBean or defines
     5  * a custom init method, and invoking the necessary callback(s) if it does.
     6  * @param beanName the bean name in the factory (for debugging purposes)
     7  * @param bean the new bean instance we may need to initialize
     8  * @param mbd the merged bean definition that the bean was created with
     9  * (can also be {@code null}, if given an existing bean instance)
    10  * @throws Throwable if thrown by init methods or by the invocation process
    11  * @see #invokeCustomInitMethod
    12  */
    13 protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
    14         throws Throwable {
    15 
    16     // 首先检查是否是InitializingBean,如果是的话就调用afterPropertiesSet()
    17     boolean isInitializingBean = (bean instanceof InitializingBean);
    18     if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
    19         if (logger.isDebugEnabled()) {
    20             logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
    21         }
    22         if (System.getSecurityManager() != null) {
    23             try {
    24                 AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
    25                     ((InitializingBean) bean).afterPropertiesSet();
    26                     return null;
    27                 }, getAccessControlContext());
    28             }
    29             catch (PrivilegedActionException pae) {
    30                 throw pae.getException();
    31             }
    32         }
    33         else {
    34             ((InitializingBean) bean).afterPropertiesSet();
    35         }
    36     }
    37 
    38     if (mbd != null && bean.getClass() != NullBean.class) {
    39         String initMethodName = mbd.getInitMethodName();
    40         if (StringUtils.hasLength(initMethodName) &&
    41                 !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
    42                 !mbd.isExternallyManagedInitMethod(initMethodName)) {
    43             // 调用自定义初始化方法
    44             invokeCustomInitMethod(beanName, bean, mbd);
    45         }
    46     }
    47 }

    7.5 注册DisposableBean
    spring中不但提供了对于初始化方法的扩展入口,同样也提供了销毁的扩展入口,对于销毁方法的扩展,除了我们熟知的配置属性destroy-method方法,用户还
    可以注册后处理器DestructionAwareBeanPostProcessor来统一处理bean的销毁方法

     1 /**
     2  * Add the given bean to the list of disposable beans in this factory,
     3  * registering its DisposableBean interface and/or the given destroy method
     4  * to be called on factory shutdown (if applicable). Only applies to singletons.
     5  * @param beanName the name of the bean
     6  * @param bean the bean instance
     7  * @param mbd the bean definition for the bean
     8  * @see RootBeanDefinition#isSingleton
     9  * @see RootBeanDefinition#getDependsOn
    10  * @see #registerDisposableBean
    11  * @see #registerDependentBean
    12  */
    13 protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
    14     AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
    15     if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
    16         if (mbd.isSingleton()) {
    17             // Register a DisposableBean implementation that performs all destruction
    18             // work for the given bean: DestructionAwareBeanPostProcessors,
    19             // DisposableBean interface, custom destroy method.
    20             // 单例模式下注册需要销毁的bean,此方法中会处理实现DisposableBean的bean,
    21             // 并且对所有的bean使用DestructionAwareBeanPostProcessor处理DisposableBean
    22             registerDisposableBean(beanName,
    23                     new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
    24         }
    25         else {
    26             // A bean with a custom scope...
    27             // 自定义scope处理
    28             Scope scope = this.scopes.get(mbd.getScope());
    29             if (scope == null) {
    30                 throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
    31             }
    32             scope.registerDestructionCallback(beanName,
    33                     new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
    34         }
    35     }
    36 }
    37 
    38 // DisposableBeanAdapter类的构造方法
    39 public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
    40         List<BeanPostProcessor> postProcessors, @Nullable AccessControlContext acc) {
    41 
    42     Assert.notNull(bean, "Disposable bean must not be null");
    43     this.bean = bean;
    44     this.beanName = beanName;
    45     this.invokeDisposableBean =
    46             (this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy"));
    47     this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
    48     this.acc = acc;
    49     String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
    50     if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
    51             !beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
    52         this.destroyMethodName = destroyMethodName;
    53         this.destroyMethod = determineDestroyMethod(destroyMethodName);
    54         if (this.destroyMethod == null) {
    55             if (beanDefinition.isEnforceDestroyMethod()) {
    56                 throw new BeanDefinitionValidationException("Could not find a destroy method named '" +
    57                         destroyMethodName + "' on bean with name '" + beanName + "'");
    58             }
    59         }
    60         else {
    61             Class<?>[] paramTypes = this.destroyMethod.getParameterTypes();
    62             if (paramTypes.length > 1) {
    63                 throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
    64                         beanName + "' has more than one parameter - not supported as destroy method");
    65             }
    66             else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
    67                 throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
    68                         beanName + "' has a non-boolean parameter - not supported as destroy method");
    69             }
    70         }
    71     }
    72     this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
    73 }
    74 
    75 /**
    76  * Search for all DestructionAwareBeanPostProcessors in the List.
    77  * @param processors the List to search
    78  * @return the filtered List of DestructionAwareBeanPostProcessors
    79  */
    80 @Nullable
    81 private List<DestructionAwareBeanPostProcessor> filterPostProcessors(List<BeanPostProcessor> processors, Object bean) {
    82     List<DestructionAwareBeanPostProcessor> filteredPostProcessors = null;
    83     if (!CollectionUtils.isEmpty(processors)) {
    84         filteredPostProcessors = new ArrayList<>(processors.size());
    85         for (BeanPostProcessor processor : processors) {
    86             if (processor instanceof DestructionAwareBeanPostProcessor) {
    87                 DestructionAwareBeanPostProcessor dabpp = (DestructionAwareBeanPostProcessor) processor;
    88                 if (dabpp.requiresDestruction(bean)) {
    89                     filteredPostProcessors.add(dabpp);
    90                 }
    91             }
    92         }
    93     }
    94     return filteredPostProcessors;
    95 }
  • 相关阅读:
    Poj 2017 Speed Limit(水题)
    Poj 1316 Self Numbers(水题)
    Poj 1017 Packets(贪心策略)
    Poj 1017 Packets(贪心策略)
    Poj 2662,2909 Goldbach's Conjecture (素数判定)
    Poj 2662,2909 Goldbach's Conjecture (素数判定)
    poj 2388 Who's in the Middle(快速排序求中位数)
    poj 2388 Who's in the Middle(快速排序求中位数)
    poj 2000 Gold Coins(水题)
    poj 2000 Gold Coins(水题)
  • 原文地址:https://www.cnblogs.com/ssh-html/p/11218628.html
Copyright © 2011-2022 走看看