精华内容
下载资源
问答
  • 主要介绍了Spring中的后置处理器BeanPostProcessor详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • Spring后置处理器详解

    千次阅读 2020-06-02 10:53:41
    spring-bean创建的生命周期与后置处理器的调用点 1.第一次调用BeanPostProcess , InstantiationAwareBeanPostProcessor中的postProcessBeforeInstantiation()方法. try { // Give BeanPostProcessors a chance to ...

    spring-bean创建的生命周期与后置处理器的调用点
    1.第一次调用BeanPostProcess , InstantiationAwareBeanPostProcessor中的postProcessBeforeInstantiation()方法.
    try {
       // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
       // 第一次调用BeanPostProcess   InstantiationAwareBeanPostProcessor这个处理器的postProcessBeforeInstantiation()方法.
       // 如果一个对象,不想通过spring进行维护, 只是想放入spring容器当中, 就实现此接口, 反回一个你需要的对象出来
       // 这边返回的对象不为null时, 这个beanName的的创建也聚完成了, spring的后置处理器不会对此对象进行操作.
       // spring不推荐使用, 是spring提供内部添加对象时调用的.
       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);
    }


    // Make sure bean class is actually resolved at this point.
    // 判断是否有InstantiationAwareBeanPostProcessors的后置处理器.
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
       Class<?> targetType = determineTargetType(beanName, mbd);
       if (targetType != null) {
          // 如果调用postProcessBeforeInstantiation返回了一个对象, 那么就直接执行后置处理器,此对象的实例化就完成.
          bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
          if (bean != null) {
             bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
          }
       }
    }


    一般来说 , 实现此接口返回的对象, 都是不需要经过spring帮我们创建对象了 , 不需要spring进行管理了.  spring不推荐我们使用, 而是交由spring内部自己调用的.
    在spring-AOP有应用场景.
    在我们开启AOP时.  添加 @EnableAspectJAutoProxy 注解.   基于spring的Import扩展  通过 ImportBeanDefinitionRegister, 帮我们注入了一个后置处理器.

    AnnotationAwareAspectJAutoProxyCreator.   此类是 InstantiationAwareBeanPostProcessor的子类, 从写了 postProcessBeforeInstantiation()方法
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
       Object cacheKey = getCacheKey(beanClass, beanName);


       if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
          if (this.advisedBeans.containsKey(cacheKey)) {
             return null;
          }
          // 再次判断beanClass中是否包含切面的注解 , 如果包含,保存到advisedBeans集合中,代表其实一个切面, 这样在bean实例化之后,
          // 执行beanPostProcess的postProcessAfterInitialization方法时, 不会对切面进行增强.
          if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
             this.advisedBeans.put(cacheKey, Boolean.FALSE);
             return null;
          }
       }


       // Create proxy here if we have a custom TargetSource.
       // Suppresses unnecessary default instantiation of the target bean:
       // The TargetSource will handle target instances in a custom fashion.
       TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
       if (targetSource != null) {
          if (StringUtils.hasLength(beanName)) {
             this.targetSourcedBeans.add(beanName);
          }
          Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
          Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
          this.proxyTypes.put(cacheKey, proxy.getClass());
          return proxy;
       }


       return null;
    }  
      2. 第二次调用beanPostProcess, 来决定使用什么构造方法来创建对象. SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors()方法.
    // 第二次调用beanPostProcess , 用来决定是什么哪个构造方法创建对象.  SmartInstantiationAwareBeanPostProcessor 的determineCandidateConstructors()方法.
    // 由后置处理器来确定返回那些够着方法, 如果拿到就使用这个构造方法实例化. spring为什么要这样做呢?
    // 我们可以通过反射直接拿到构造方法呀.
    // beanPostProcess认为如果你没有没有构造方法,或者你构造方法是默认的空参构造, 那么此时返回的constructor= null.
    // spring就认为你不存在特殊的构造方法, 所以直接跳过调用空参构造创建对象, 如果有特殊的构造方法,那么constructor != null,
    // 就会使用你这个有参构造方法来创建对象.
    // 但是如果有两个构造方法时 , 并且你没有指定primary的构造方法时, 也会返回null , 因为spring不知道你要使用哪个构造方法,所以还是让你走空参构造创建对象.
    // 简单来说 , 如果有有且只有一个有参构造方法, 那么就返回这个有参构造方法, 如果有多个构造方法 , 就使用空参构造创建.
    // 但是如果在解析beanDefinotion给他添加了构造方法, 那么就会使用到我们添加的构造方法.
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    // 如何使用有参构造方法来创建对象呢?
    // 有四个判断条件.
    // 1. 通过上方,后置处理器,找到了唯一的有参构造
    // 2. BeanDefinition设置为自动创建的模式  AUTOWIRE_CONSTRUCTOR
    // 3. BeanDefinition我们设置了ConstructorArgumentValues, 还记得mybatis吗? 我们扫描完BeanDefinition后,给BeanDefinition设置使用什么构造参数和使用哪个beanClass.
    // 4. 调用singletonObject是,传入的args就不为空, 是有值的, 明确告诉你, 我需要构造方法创建.
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
          mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
       return autowireConstructor(beanName, mbd, ctors, args);
    }

       3. 第三次调用beanPostProcess, 此方法用来缓存bean中的注解信息. 此时对象已经创建出来, 但是spring还没有创建成功, 因为各种属性还未添加.
                MergedBeanDefinitionPostProcessor 的 postProcessMergedBeanDefinition()方法.

    synchronized (mbd.postProcessingLock) {
       if (!mbd.postProcessed) {
          try {
             //第三次调用 beanPostProcess , MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition()方法
             applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
          }
          catch (Throwable ex) {
             throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                   "Post-processing of merged bean definition failed", ex);
          }
          mbd.postProcessed = true;
       }
    }

      4. 第四次调用beanPostProcess, 用来提前暴露对象. spring认为此时, 对象仅仅是new了出来, 但是没有创建完成 , 对象走完spring的生命周期, 放入singletonObjects中, spring才算对象创建完成. 此时会把bean保存到singleonFactories中. 相当于一个中间集合, 如果对象在创建中, 因为引用其他对象时 , getSingleton()方法 会先到singletonFactories中获取, 如果获取不到 , 再通过 creatBean()创建对象 , 用来解决spring的循环引用问题 .
                SmartInstantiationAwareBeanPostProcessor 的 getEarlyBeanReference() 方法.
    if (earlySingletonExposure) {
       if (logger.isDebugEnabled()) {
          logger.debug("Eagerly caching bean '" + beanName +
                "' to allow for resolving potential circular references");
       }
       // 会把正在创建的bean保存到singletonFactories中
       // 第四次调用beanPostProcess , SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference()方法, 用来解决循环依赖的
       addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    5. 第五次调用beanPostProcess, 用来判断你的bean需不需要完成属性填充 , 如果实现此接口 , 返回false , 那么spring不会帮我们填充属性.
                InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法.

    // 第五次执行beanPostProcess , InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
       for (BeanPostProcessor bp : getBeanPostProcessors()) {
          if (bp instanceof InstantiationAwareBeanPostProcessor) {
             InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
             if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                return;
             }
          }
       }
    }

       6. 第六次调用beanPostProcess,
            AutowireAnnotationBeanPostProcessor 中的 postProcessProperrtyValues()方法.  主要使用来帮我们完成属性注入的 .
            CommonAnnotationBeanPostProcessor 中的  postProcessProperrtyValues()方法.  主要是用来处理@Resource的.
    // 判断autowireMode是什么类型, 默认其实是 AUTOWIRE_BY_NO.
    // 通过byName 或者 byType 拿到对应的属性, 其中spring会进行过滤 , 赋值给pvs ,让后置处理器去处理.
    int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
       MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
       // Add property values based on autowire by name if applicable.
       if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
          autowireByName(beanName, mbd, bw, newPvs);
       }
       // Add property values based on autowire by type if applicable.
       if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
          autowireByType(beanName, mbd, bw, newPvs);
       }
       pvs = newPvs;
    }

    protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
       Set<String> result = new TreeSet<>();
       // 拿到我们手动设置的属性. 我们拿到beanDefinition后可以手动设置属性.
       PropertyValues pvs = mbd.getPropertyValues();
       // 拿到class 的所有属性.
       PropertyDescriptor[] pds = bw.getPropertyDescriptors();
       for (PropertyDescriptor pd : pds) {
          // 对所有的属性进行过滤.  那些属性是我们想要的.
          // 1. 需要set方法.
          // 2. spring过滤接口, 不存在.
          // 3. pvs中不包含的pd ,  我们手动添加给beanDefinition也需要过滤掉, 因为set方法肯定是class自己的,而不是我们手动添加的.
          // 4. 简单类型的也忽略掉.
          if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
                !BeanUtils.isSimpleProperty(pd.getPropertyType())) {
             result.add(pd.getName());
          }
       }
       return StringUtils.toStringArray(result);
    }


    if (hasInstAwareBpps) {

       //在这一步处理使用后置处理器来处理对象, 例如require , autowire 注解
       // 第六次调用beanPostProcess , InstantiationAwareBeanPostProcessor的postProcessPropertyValues()方法.
       for (BeanPostProcessor bp : getBeanPostProcessors()) {
          if (bp instanceof InstantiationAwareBeanPostProcessor) {
             InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
             pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
             if (pvs == null) {
                return;
             }
          }
       }
    }

    @Override
    public PropertyValues postProcessPropertyValues(
          PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {


       InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
       try {
          // 通过inject注入属性.
          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;
    }


        @Override
       protected 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());
             Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
             Assert.state(beanFactory != null, "No BeanFactory available");
             TypeConverter typeConverter = beanFactory.getTypeConverter();
             try {
                // 关键代码 , 从spring的beanFactory中获取对象
                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);
          }
       }
    }

    public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
          throws BeansException {

        // 调用到geiBean() , 然后通过getSingleton()获取.
       return beanFactory.getBean(beanName);
    }

       7.  第七次调用beanPostProcess,   此时对象已经创建成功, 并且属性填充完毕. 基本上一个bean对象已经创建完成.

    if (mbd == null || !mbd.isSynthetic()) {
       // BeanPostProcess有两个方法 ,这里先执行  postProcessBeforeInitialization 方法.
       // 第七次执行BeanPostProcess , 真正执行的BeanPostProcess的postProcessBeforeInitialization()方法.
       // 之前执行的都是实现类中自己定义的扩展功能的方法.
       wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }


    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        //如果你的bean是ImportAware

       if (bean instanceof ImportAware) {
          ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class);
          AnnotationMetadata importingClass = ir.getImportingClassFor(bean.getClass().getSuperclass().getName());
          if (importingClass != null) {
             ((ImportAware) bean).setImportMetadata(importingClass);
          }
       }
       return bean;
    }

      8. 第八次调用beanPostProcess, 创建对象的最后一步, aop的代理就是在此处创建.
    if (mbd == null || !mbd.isSynthetic()) {
       // 处理BeanPostProcess的另一个方法 . postProcessAfterInitialization , aop就在此时做的.
       // 第八次执行beanPostProcess, 真正执行的beanPostProcess的postProcessAfterInitialization()方法.
       wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }


    protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
          @Nullable Object[] specificInterceptors, TargetSource targetSource) {
       if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
          AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
       }
       // spring写的代理工厂 , 工厂模式的使用
       ProxyFactory proxyFactory = new ProxyFactory();
       // 这只proxyFactory工厂的属性, 从这个类中, 因为此类继承 ProxyConfig
       proxyFactory.copyFrom(this);

       // 判断使用那种方式进行代理 , cglib 还是 jdk
       // 因为在new ProxyFactory工厂时, 父类会创建 AopProxyFactory工厂,
       // 此类的createAopProxy(),中调用proxyTargetClass属性, 如果是true,就使用cglib , spring默认是false.
       if (!proxyFactory.isProxyTargetClass()) {
          if (shouldProxyTargetClass(beanClass, beanName)) {
             proxyFactory.setProxyTargetClass(true);
          }
          else {
             evaluateProxyInterfaces(beanClass, proxyFactory);
          }
       }

       // 拿到我们切面中的所有方法.
       Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
       proxyFactory.addAdvisors(advisors);
       proxyFactory.setTargetSource(targetSource);
       customizeProxyFactory(proxyFactory);
       proxyFactory.setFrozen(this.freezeProxy);
       if (advisorsPreFiltered()) {
          proxyFactory.setPreFiltered(true);
       }
       return proxyFactory.getProxy(getProxyClassLoader());
    }


    以上就是spring扫描的我们对应的类之后 , 通过beanDefinition创建对象的流程. 欢迎讨论
    ————————————————

    展开全文
  • spring后置处理器

    千次阅读 2019-01-12 14:27:09
    bean的后置处理器,主要在bean初始化前后工作。接口定义: public interface BeanPostProcessor { // 在初始化方法(如:afterPropertiesSet 或 init-method)执行前触发 @Nullable default Object ...

    1. BeanPostProcessor

    bean的后置处理器,主要在bean初始化前后工作。接口定义:

    public interface BeanPostProcessor {
    
    	// 在初始化方法(如:afterPropertiesSet 或 init-method)执行前触发
    	@Nullable
    	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    		return bean;
    	}
    
    	// 在初始化方法(如:afterPropertiesSet 或 init-method)执行后触发
    	@Nullable
    	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    		return bean;
    	}
    
    }
    

    2. InstantiationAwareBeanPostProcessor

    InstantiationAwareBeanPostProcessor继承于BeanPostProcessor,主要在实例化bean前后工作; AOP创建代理对象就是通过该接口实现。接口定义:

    public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
    
    	// 对象实例化前
    	@Nullable
    	default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    		return null;
    	}
    
    	// 对象实例化后
    	default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
    		return true;
    	}
    
    	@Nullable
    	default PropertyValues postProcessPropertyValues(
    			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
    
    		return pvs;
    	}
    
    }
    

    3. BeanFactoryPostProcessor

    bean工厂的后置处理器,在bean定义(bean definitions)加载完成后,bean尚未初始化前执行。接口定义:

    public interface BeanFactoryPostProcessor {
    
    	/**
    	 * Modify the application context's internal bean factory after its standard
    	 * initialization. All bean definitions will have been loaded, but no beans
    	 * will have been instantiated yet. This allows for overriding or adding
    	 * properties even to eager-initializing beans.
    	 * @param beanFactory the bean factory used by the application context
    	 * @throws org.springframework.beans.BeansException in case of errors
    	 */
    	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
    
    }
    

    4. BeanDefinitionRegistryPostProcessor

    BeanDefinitionRegistryPostProcessor继承于BeanFactoryPostProcessor。其自定义的方法postProcessBeanDefinitionRegistry会在bean定义(bean definitions)将要加载,bean尚未初始化前真执行,即在BeanFactoryPostProcessor的postProcessBeanFactory方法前被调用。接口定义:

    public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    
    	/**
    	 * Modify the application context's internal bean definition registry after its
    	 * standard initialization. All regular bean definitions will have been loaded,
    	 * but no beans will have been instantiated yet. This allows for adding further
    	 * bean definitions before the next post-processing phase kicks in.
    	 * @param registry the bean definition registry used by the application context
    	 * @throws org.springframework.beans.BeansException in case of errors
    	 */
    	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
    
    }
    
    展开全文
  • 这里要介绍的是Spring的扩展类点之一的:BeanPostProcessor. 废话不多说,开搞! 1.准备代码 TestProcessor类 @Component public class TestProcessor implements BeanPostProcessor ,PriorityOrdered{ @Override ...

    这里要介绍的是Spring的扩展类点之一的:BeanPostProcessor. 废话不多说,开搞!

    1.准备代码

    在这里插入图片描述

    • TestProcessor类
    @Component
    public class TestProcessor implements BeanPostProcessor ,PriorityOrdered{
    	@Override
    	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    		if (beanName.equals("personService")){
    			System.out.println("BeforeInitialization1");
    		}
    		return bean;
    	}
    	@Override
    	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    		if (beanName.equals("personService")){
    			System.out.println("AfterInitialization1");
    		}
    		return bean;
    	}
    	@Override
    	public int getOrder() {
    		return 200;
    	}
    }
    
    • TestProcessor2类
    @Component
    public class TestProcessor2 implements BeanPostProcessor,PriorityOrdered {
       @Override
       public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
          if (beanName.equals("personService")){
             System.out.println("BeforeInitialization2");
          }
          return bean;
       }
    
       @Override
       public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
          if (beanName.equals("personService")){
             System.out.println("AfterInitialization2");
          }
          return bean;
       }
       @Override
       public int getOrder() {
          return 199;
       }
    }
    
    • PersonService类
    @Component
    public class PersonService {
       public PersonService() {
          System.out.println("personService构造方法执行了");
       }
       @PostConstruct
       public void init(){
          System.out.println("init方法执行了");
       }
    }
    
    • PersonService2类
    @Component
    public class PersonService2 implements ApplicationContextAware {
       private ApplicationContext applicationContext;
       @Override
       public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
                this.applicationContext = applicationContext;
          System.out.println("全局对象:"+ applicationContext);
       }
    }
    
    • SpringConfiguration类
    @ComponentScan("com.v1")
    public class SpringConfiguration {
    
    }
    
    • Test01类
    public class Test01 {
       public static void main(String[] args) {
          //这个构造方法会把Spring所有的环境都准备好
          AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
       }
    }
    

    2.点击 AnnotationConfigApplicationContext

    public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
       //这个类有父类,所以会先初始化父类的构造方法,接着初始化自己的构造方法
       //调用无参构造方法进行初始化一个读取器和扫描仪
       this();
       //把配置类加载进 DefaultListableBeanFactory 的map集合中
       //配置类可以一次性传多个,这个方法执行后,只是把配置类加载进了 DefaultListAbleBeanFactory的map集合中
       //还没有扫描其他的的加了组件的类
       register(annotatedClasses);
       //实例化所有被加了组件的对象
       refresh();
    }
    

    3.点击 refresh() 方法

    @Override
    public void refresh() throws BeansException, IllegalStateException {
       synchronized (this.startupShutdownMonitor) {
          //调用容器准备刷新的方法,获取容器的当时时间,同时给容器设置同步标识
          //这个方法不是重点,可以暂时认为他不干任何事情
          prepareRefresh();
    
          //获取工厂对象 ,本质是DefaultListableBeanFactory对象
          //其实读取xml文件变成beanDefinition,也是在这里面完成的
          //所以这里面的功能和register(annotatedClasses);功能很像
          //一个是是从xml文件中读取配置信息,一个是通过类的注解读取信息
          ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
          //为BeanFactory配置类加载器、后置处理器等等
          //这个方法比较重要
          prepareBeanFactory(beanFactory);
           
           //剩余的代码省略.....
       }
    

    4.点击 prepareBeanFactory 方法

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    
       //添加一个类加载器
       beanFactory.setBeanClassLoader(getClassLoader());
    
       //bean的表达式解析,以后再讲,在前台页面可以获取到bean表达式的一些属性
       beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    
       //对象与string类型的转换  <property >
       beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    
    
       //重要方法
       //为Spring添加后置处理器 ApplicationContextAwareProcessor 实现了BeanProcessor接口
       //我们主要查看 重写接口的 postProcessBeforeInitialization ()方法
       //主要作用:判断当前bean对象实现了里面的那些接口,从而在bean类获取对应的对象
       //一般我们会实现 ApplicationContextAware 接口获取 applicationContext
       beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    
       //以下是添加自动注入忽略的列表,不是重点
       beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
       beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
       beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
       beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
       beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
       beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    
       //等讲到bean的实例化的过程时,会说明
       beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
       beanFactory.registerResolvableDependency(ResourceLoader.class, this);
       beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
       beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    
     //这个ApplicationListenerDetector作用: 某个类实现了ApplicationListener接口,可以获取到一个ApplicationEvent对象
       //ApplicationEvent对象存储有reader,scanner,registry,beanFactory等对象
       //注意实现ApplicationListener的前提是,这个bean必须是单例的
       beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    
        //剩余的代码省略.....
    }
    

    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

    解析这个方法之前,我们看一下 BeanFactory工厂里面到底存放了哪些数据

    在这里插入图片描述

    粉色部分就是 BeanFactory 的示意图

    • 绿色部分: Spring初始化的时候,所有的beanDefinition都存储在这个beanDefinitionMap集合中
    • 黄色部分:beanDefinitionNames集合存储所有 beanDefinition的名称
    • 深紫部分: beanPostProcessors集合存储着所有的后置处理器,也就是实现了 BeanPostProcessor接口的类
    • 浅绿部分: getBeanNamesForType, beanFactory中的一个方法,通过类型得到一个beanName
    • 浅紫部分: singletonObjects,实例化后的类会存储在这个集合中

    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this))

    这个方法把 ApplicationContextAwareProcessor 添加进了 beanPostProcessors,说明这个类是一个实现了

    BeanPostProcessors的后置处理器

    5.点击 ApplicationContextAwareProcessor `

    查看 ApplicationContextAwareProcessor,果然它实现了 BeanPostProcessor

    6.点击 BeanPostProcessor

    
    public interface BeanPostProcessor {
         
       /* 
        * 在bean的初始化之前执行
        */
       @Nullable
       default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
          return bean;
       }
       
       /*
        * 在bean的初始化之后执行
        */
       @Nullable
       default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
          return bean;
       }
    
    }
    
    • BeanPostProcessor是Spring框架提供的一个扩展类点之一
    • 扩展类点其实有很多种的 例如实现 BeanFactoryPostProcessor接口也是
    • BeanPostProcessor作用:
      • 通过实现BeanPostProcessor接口,程序员就可以插手bean的实例化过程,从而减轻beanFactory的负担
      • 这个接口可以被多个类实现,会形成一个列表, 通过实现PriorityOrdered可以改变实现类的执行顺序,getOrder返回值越小越优先执行
      • AOP的就是在bean实例化后期将切面逻辑织入bean实例中的
      • AOP也是通过BeanPostProcessor和IOC容器建立起了联系

    Spring默认提供很多BeanPostProcessor的实现类
    其实这个接口的本身方法特别的简单,简单到令人发指,但是他的实现类巨多,实现类的方法内的逻辑复杂的程 度也令人发指

    前面我们准备了两个处理器 TestProcessor,TestProcessor2都实现了 BeanPostProcessorPriorityOrdered

    • TestProcessor类
    @Component
    public class TestProcessor implements BeanPostProcessor ,PriorityOrdered{
    	@Override
    	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            //所有的类的实例化过程中都会执行执行实现了BeanPostProcessor后置处理器
            //为了避免其他类做实例化的时候,也打印BeforeInitialization1,影响测试
    		if (beanName.equals("personService")){
    			System.out.println("BeforeInitialization1");
    		}
    		return bean;
    	}
    	@Override
    	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    		if (beanName.equals("personService")){
    			System.out.println("AfterInitialization1");
    		}
    		return bean;
    	}
    	@Override
    	public int getOrder() {
    		return 200;
    	}
    }
    
    • TestProcessor2类
    @Component
    public class TestProcessor2 implements BeanPostProcessor,PriorityOrdered {
       @Override
       public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
          if (beanName.equals("personService")){
             System.out.println("BeforeInitialization2");
          }
          return bean;
       }
    
       @Override
       public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
          if (beanName.equals("personService")){
             System.out.println("AfterInitialization2");
          }
          return bean;
       }
       @Override
       public int getOrder() {
          return 199;
       }
    }
    

    两个后置处理器都实现了 BeanPostProcessor的init和after方法,实现了 PriorityOrderedgetOrder方法

    实现 getOrder的后置处理器,返回值为 int 类型,返回值越小,执行的顺序越靠前

    我们回到 Test01运行测试类

    测试结果:

    personService构造方法执行了
    BeforeInitialization2
    BeforeInitialization1
    init方法执行了
    AfterInitialization2
    AfterInitialization1
    全局对象:org.springframework.context.annotation.AnnotationConfigApplicationContext@100955a, started on Sun Dec 08 11:48:03 CST 2019
    

    7.我们回到 ApplicationContextAwareProcessor类中

    既然我们已经知道了 BeanPostProcessors的作用,我们看看 ApplicationContextAwareProcessor这个Spring内部的后置处理器的init方法和after方法里面到底干了哪些事

    class ApplicationContextAwareProcessor implements BeanPostProcessor {
    
    	private final ConfigurableApplicationContext applicationContext;
    
    	private final StringValueResolver embeddedValueResolver;
    	public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
    		this.applicationContext = applicationContext;
    		this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
    	}
    
    
    	@Override
    	@Nullable
    	public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
    		AccessControlContext acc = null;
           //这个方法不会进入
    		if (System.getSecurityManager() != null &&
    				(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
    						bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
    						bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
    			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
    		}
    
    		if (acc != null) {
    			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    				invokeAwareInterfaces(bean);
    				return null;
    			}, acc);
    		}
    		else {
    			//这个重点
    			invokeAwareInterfaces(bean);
    		}
    
    		return bean;
    	}
    
    	/**
    	 * 判断当前的bean,实现了什么类型的接口,然后根据判断设置类
    	 * @param bean
    	 */
    	private void invokeAwareInterfaces(Object bean) {
            
    		if (bean instanceof Aware) {
    	//(1)如果bean实现了EnvironmentAware接口,可以获取环境对象
    			if (bean instanceof EnvironmentAware) {
    				((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
    			}
                
    	//(2)如果bean实现了EmbeddedValueResolverAware接口,可以获取embeddedValueResolver对象
    			if (bean instanceof EmbeddedValueResolverAware) {
    				((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
    			}
                
    	//(3)如果bean实现了ResourceLoaderAware接口,可以获取applicationContext工厂对象
    			if (bean instanceof ResourceLoaderAware) {
    				((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
    			}
                
     //(4)如果bean实现了ApplicationEventPublisherAware接口,可以获取applicationContext工厂对象
    			if (bean instanceof ApplicationEventPublisherAware) {
    				((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
    			}
                
     //(5)如果bean实现了MessageSourceAware接口,可以获取applicationContext工厂对象
    			if (bean instanceof MessageSourceAware) {
    				((MessageSourceAware) bean).setMessageSource(this.applicationContext);
    			}
                
    //(6)如果该bean实现了ApplicationContextAware接口 ,那么就把工厂applicationContext,传进去
    //在bean的类中重写ApplicationContextAware的set方法 就可以在该bean中获取到整个工厂
    //这时候想获取哪个对象都可以了
    			if (bean instanceof ApplicationContextAware) {
    				((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
    			}
    		}
    	}
    
    	@Override
    	public Object postProcessAfterInitialization(Object bean, String beanName) {
    		return bean;
    	}
    
    }
    

    通过查看 ApplicationContextAwareProcessor处理器,我们发现 ,它同样是实现了 BeanPostFactory的两个方法 postProcessBeforeInitializationpostProcessAfterInitialization方法,但是 后置方法并没有干任何事,我们重点查看 前置方法

    ApplicationContextAwareProcessor方法中,调用 invokeAwareInterfaces方法,

    查看 invokeAwareInterfaces方法,我们查询,只要实现某一个接口就能获取相应的对象

    例如在准备代码中,我们的 PersonService2实现了 ApplicationContextAware接口

    @Component
    public class PersonService2 implements ApplicationContextAware {
       private ApplicationContext applicationContext;
    	@Override
    	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
                this.applicationContext = applicationContext;
    		System.out.println("全局对象:"+ applicationContext);
    	}
    }
    

    实现了 setApplicationContext就可以获取全局对象

    假设你这样一个需求,需要初始化的时候获取到Spring的全局对象,那么你就可以实现 ApplicationContextAware

    总结一下 ApplicationContextAwareProcessor到底干了哪些事?

    1. 实现了 BeanPostProcessors接口
    2. postProcessBeforeInitialization方法里面执行 invokeAwareInterfaces方法
    3. invokeAwareInterfaces方法中,判断当前的Bean实现了哪些接口,如果实现了某个接口就可以获取对应的对象

    8.我们回到 第四步 点击 prepareBeanFactory `方法

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    
       //添加一个类加载器
       beanFactory.setBeanClassLoader(getClassLoader());
    
       //bean的表达式解析,以后再讲,在前台页面可以获取到bean表达式的一些属性
       beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    
       //对象与string类型的转换  <property >
       beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    
    
       //重要方法
       //为Spring添加后置处理器 ApplicationContextAwareProcessor 实现了BeanProcessor接口
       //我们主要查看 重写接口的 postProcessBeforeInitialization ()方法
       //主要作用:判断当前bean对象实现了里面的那些接口,从而在bean类获取对应的对象
       //一般我们会实现 ApplicationContextAware 接口获取 applicationContext
       beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    
       //以下是添加自动注入忽略的列表,不是重点
       beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
       beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
       beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
       beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
       beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
       beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    
       //等讲到bean的实例化的过程时,会说明
       beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
       beanFactory.registerResolvableDependency(ResourceLoader.class, this);
       beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
       beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    
     //这个ApplicationListenerDetector作用: 某个类实现了ApplicationListener接口,可以获取到一个ApplicationEvent对象
       //ApplicationEvent对象存储有reader,scanner,registry,beanFactory等对象
       //注意实现ApplicationListener的前提是,这个bean必须是单例的
       beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    
        //剩余的代码省略.....
    }
    

    在该方法中 ,不仅添加了 ApplicationContextAwareProcessor,这个后置处理器,其实还添加了 ApplicationListenerDetector这个处理器

    9.点击 ApplicationListenerDetector

    我们主要查看 postProcessAfterInitialization方法

    @Override
    	public Object postProcessAfterInitialization(Object bean, String beanName) {
    		//判断当前的bean是否实现了ApplicationListener这个接口,如果没有实现直接跳过
    		if (bean instanceof ApplicationListener) {
    			//如果有实现,则判断当前的bean实现是单例的
    			//singletonNames存储用户所有的bean,
    			// key值为 beanName ,value值为Boolean值 false 代表为不是单例  true代表为单例
    			Boolean flag = this.singletonNames.get(beanName);
    			if (Boolean.TRUE.equals(flag)) {
    
    				this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
    			}
    			else if (Boolean.FALSE.equals(flag)) {
    				if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
    					// inner bean with other scope - can't reliably process events
    					logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
    							"but is not reachable for event multicasting by its containing ApplicationContext " +
    							"because it does not have singleton scope. Only top-level listener beans are allowed " +
    							"to be of non-singleton scope.");
    				}
    				//如果不是单例的,删除掉
    				this.singletonNames.remove(beanName);
    			}
    		}
    		return bean;
    	}
    

    这个方法主要作用:

    执行了 ApplicationListener,必须是 单例的,才可以获取到相应的对象

    视频讲解:

    <https://www.bilibili.com/video/av67899876?p=4>

    视频为自己学习的时候录制的,也方便自己以后看

    Spring5源码地址:

    <https://gitee.com/zouchangfu/spring_5_source_code>

    Spring5源码都是已经构建好的了,无需再使用gradle进行构建了,直接打开就可以跑起来

    写在最后:

    大二学生一枚,挤时间写博客不容易,看完顺手点个赞,你的点赞是对我最大的鼓励

    展开全文
  • ApplicationListenerDetector:事件监听器的后置处理器
  • Spring BeanFactory后置处理器详解之配置类解析过程BeanFactoryPostProcessor实现方式BeanFactory后置处理器源码分析invokeBeanFactoryPostProcessors分析 BeanFactoryPostProcessor BeanFactoryPostProcessor是...
  • Spring之BeanPostProcessor(后置处理器)介绍

    万次阅读 多人点赞 2019-03-03 13:10:33
      该接口我们也叫后置处理器作用是在Bean对象在实例化和依赖注入完毕后,在显示调用初始化方法的前后添加我们自己的逻辑。注意是Bean实例化触发的。接口的源码如下 public interface BeanPostProcessor { .....
  • 后置处理器 如果我们想在Spring容器中完成bean实例化、配置以及其他初始化方法前后要添加一些自己逻辑处理。我们需要定义一个或多个BeanPostProcessor接口实现类,然后注册到Spring IoC容器中。 代码示例: ...
  • 今天,通过这篇文章,我想带大家先了解下什么是spring后置处理器,然后利用spring的后置处理器我们自己来手写一个springAop,来完成和springAop一样的功能!让你可以对你的面试官说:你精通AOP! 在开始之前呢,我...
  • Spring对bean的赋值, 注入其它组件, 生命周期注解功能,@Async等等功能,在低层都是通过底层对BeanPostProcessor也就是后置处理器的支持实现的。下面看几个常见的后置处理器,具体的spring源码将在以后分析。 1....
  • spring bean后置处理器

    2019-10-08 23:09:45
    最理想的情况下,让实现类去实现Ordered最理想的,但是,在默认情况下,Spring容器会根据后置处理器的定义顺序来依次调用,比如: < beans xmlns = " http://www.springframework.org/schema/beans " ...
  • spring中的后置处理器

    千次阅读 2018-03-19 15:44:32
    spring中,对bean的扩展集中在各种beanPostProcessor中,下面是一些后置处理器调用的地方以及调用方法: 1、InstantiationAwareBeanPostProcessor postProcessBeforeInstantiation(beanClass, beanName) 在...
  • 1.第一次调用作用,bean的实例化前 (一般都是返回null,不为空,就不会走下面了) 2.创建bean生命周期,Object ...1.实例化里面–找构造器时 – 通过SmartInstantiationAwareBeanPostProcessor 后置处理器来确定选...
  • Spring后置处理器

    2020-03-15 21:44:28
    // 显示添加后置处理器 bf.addBeanPostProcessor(bf.getBean(MyBeanPostProcessor.class)); 若定义多个BeanPostProcessor实现类,可以通过实现Ordered接口,定义顺序 2. BeanFactoryPostProcessor Spring IOC容器...
  • spring源码:九大后置处理器

    千次阅读 2020-05-31 09:14:11
    spring在完成一个bean的初始化、实例化的过程中,会用到九个后置处理器;本文梳理出这九个后置处理器 九大后置处理器 spring在初始化的过程中,会在九个地方分别调用了五个后置处理的九个方法 第一次调用后置处理器...
  • Spring经过XML解析获取到了所有需要实例化Bean的信息并读取到BeanDefinition后,就保存在了...而beanFactory后置处理器,既BeanFactoryPostProcessor就是用来改变bean定义的。 invokeBeanFactoryPostProcessors
  • createBean resolveBeforeInstantiation **InstantiationAwareBeanPostProcessor**.applyBeanPostProcessorsBeforeInstantiation applyBeanPostProcessorsAfterInitialization
  • 与ApplicationContext容器共生的后置处理器(重要) 1.ConfigurationClassPostProcessor :处理加了@SpringBootApplication注解的启动类 2.AutowiredAnnotationBeanPostProcessor:完成Bean的@Autowired注解的自动...
  • 总结下Spring几个基础后置处理器的使用方法和调用时机 二 BeanFactoryPostPrecessor 作用于所有被Spring管理的类都转换成BeanDifinition缓存到BeanDifinitionMap中但还都未进行实例化中调用,可以在此时操作...
  • Spring Bean前置后置处理器的使用

    万次阅读 2018-09-24 21:17:11
    Spirng中BeanPostProcessor和InstantiationAwareBeanPostProcessorAdapter两个接口都可以实现对bean前置后置处理的效果,那这次先讲解一下BeanPostProcessor处理器的使用 先看一下BeanPostProcessor接口的源码,它...
  • 今天在看源码的时候,有些后置处理器莫名其妙就加了进来,因此我就看看它是从哪来的? Spring内部会加载的选项如下 /** * Register all relevant annotation post processors in the given registry. * @param ...
  • Spring 后置处理器源码

    2020-02-20 17:03:38
    在《几种自定义Spring生命周期的初始化和销毁方法》最后一段描述了启动 Spring 容器过程中,初始化和销毁方法的执行时机,那么在 Spring 中是如何做到的呢? 注册主配置类 Spring 使用...
  • import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.MethodParameter; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType;...
  • https://blog.csdn.net/baomw/article/details/84262006
  • spring中的前置处理器和后置处理器区别

    千次阅读 热门讨论 2020-09-17 17:14:41
    SpringIOC容器它会以某种方式,加载配置文件中的 信息,将其解析为一个个的BeanDefinition.之后将BeanDefinition注册到容器之中。Spring IOC容器在实现的时候经过的过程可以使用如下图片表示: 分为两个主要部分: ...
  • 今天我们就先来讲解Spring中一个非常重要的概念:后置处理器Spring中有两种非常重要的后置处理器: bean工厂后置处理器 bean后置处理器 其中Bean工厂后置处理器就是本节要讲的,它们会在Spring启动过程中,在...
  • 这些后置处理器spring实现自定义功能或者扩展spring的核心所在 一、postProcessBeforeInitialization 该方法属于InstantiationAwareBeanPostProcessor后置处理器 public interface ...
  • 最近在恶啃Spring源码,就读到一个很有意思的东西BeanPostProcessor,正式的名字叫做Spring后置处理器,这个东西非常的强大,强大到可以让我们干预Bean的创建过程,写出来分享给大家。更多Spring内容进入【Spring...
  • 将类加进容器,再spring容器中bean初始化的时候就会触发这两个方法。 在spring初始化的时候执行refresh方法,在refresh中的finishBeanFactoryInitialization方法进行getbean操作,由于是第一次使用,没有这个bean便...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,951
精华内容 7,580
关键字:

spring后置处理器的作用

spring 订阅