精华内容
下载资源
问答
  • spring bean后置处理器

    2019-10-08 23:09:45
    一个context中的后置处理器实现类不是针对某一个的bean,这个context中的所有bean的产生过程都回去调用这个后置处理器,为了有针对性,可以通过bean的id来执行特异话的操作。 2 后置处理器实现类 ...

    1后置处理器是什么?

    一个类,实现了接口BeanPostProcessor 定义的两个方法,这两个方法分别是:postProcessBeforeInitialization和postProcessAfterInitialization,顾名思义,就是分别在bean的init-method前后进行分别执行这两个方法。
    多后置处理器的有序性的
    bean在使用的过程中可以经过多个后置预处理的处理,但是,一般情况下,多个实现后置处理器接口的类是有先后顺序的,为了让IOC明白后置处理器之间的先后顺序,类还要实现Ordered接口,通过接口里的order属性来控制后处理器的先后顺序,默认为0,为最高优先级。
    同一个容器中的后置处理器是通用的
    一个context中的后置处理器实现类不是针对某一个的bean,这个context中的所有bean的产生过程都回去调用这个后置处理器,为了有针对性,可以通过bean的id来执行特异话的操作。

    2 后置处理器实现类

    BeanPostProcessor 接口源码

    	@Nullable
    	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    		return bean;
    	}
    	@Nullable
    	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    		return bean;
    	}
    

    可见,返回值必须为非null,且必须是Object类型,和从context中get出来的一致。由于是有默认实现,因此,不是必须要重写方法的。现在看一个后处理器类的实例:

    package 后置处理器;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    
    public class PostProcessorExample implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            if ("chinese".equals(beanName)) {
                System.out.println("后置处理器,初始化前处理的bean的id是:" + beanName);
            } else {
                System.out.println("后置处理器,初始化前处理的bean的id是:" + beanName);
            }
            return bean;
        }
    
    }
    

    通过beanName对处理的bean进行针对性的区分、处理。

    3 后置处理器实现类bean配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="chinese" class="初始化和销毁回调.Chinese">
        </bean>
    
        <bean id="american" class="初始化和销毁回调.American">
        </bean>
    
        <bean id="beanPostProcessor" class="后置处理器.PostProcessorExample">
        </bean>
    
    </beans>
    

    4 运行调用

    主类

    package 后置处理器;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    
    public class PostProcessorExample implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            if ("chinese".equals(beanName)) {
                System.out.println("后置处理器,初始化前处理的bean的id是:" + beanName);
            } else {
                System.out.println("后置处理器,初始化前处理的bean的id是:" + beanName);
            }
    
            return bean;
        }
    
    }
    

    其中America类实现了InitializingBean, DisposableBean这两个接口,xml配置元数据中不配置也自带初始化和销毁方法,Chinese完全没有指定初始化和销毁方法,因此,控制台输出是:

    后置处理器,初始化前处理的bean的id是:chinese
    后置处理器,初始化前处理的bean的id是:american
    American 初始化回调函数
    American 销毁回调函数
    

    5多后置处理器调用

    最理想的情况下,让实现类去实现Ordered最理想的,但是,在默认情况下,Spring容器会根据后置处理器的定义顺序来依次调用,比如:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans    http://www.springframework.org/schema/beans/spring-beans.xsd">
      <!-- bean定义 -->  
      <bean id="narCodeService" class="com.test.service.impl.NarCodeServiceImpl">
      </bean>
      <bean id="postProcessor" class="com.test.spring.PostProcessor"/>
      <bean id="postProcessorB" class="com.test.spring.PostProcessorB"/>
    </beans>
    

    在bean配置元数据,就回让IOC容器最后再调用B后置处理器。但是!官方还是建议去实现顺序接口来显式定义的后置处理器的实现顺序!

    展开全文
  • BeanPostProcessor接口拆解功能描述:如何使用:定义要处理的接口类型添加实际需要处理的类定义后置处理器编写测试类执行日志后置处理器加载解析registerBeanPostProcessors注册拦截bean创建的bean处理器...

    功能描述:

    • 实现BeanPostProcessor接口允许我们可以对所有bean在创建之前和之后做一些自己的处理

    • BeanPostProcessor 接口定义:

      public interface BeanPostProcessor {
      
      	/**
      	* 前置处理,实例化bean之前对bean进行处理
      	*/
      	@Nullable
      	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
      		return bean;
      	}
      
      	/**
      	* 后置处理,实例化bean之后对bean进行处理
      	*/
      	@Nullable
      	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      		return bean;
      	}
      
      }
      

    如何使用:

    1. 定义要处理的接口类型

      public interface TestBeanPostProcessorInterface {
      
          String getPassword();
      
          void setPassword(String password);
      }
      
    2. 添加实际需要处理的类

      import org.springframework.stereotype.Component;
      
      @Component
      public class UserInfoVO implements TestBeanPostProcessorInterface {
      
          private String password = "password";
      
          @Override
          public String getPassword() {
              return password;
          }
      
          @Override
          public void setPassword(String password) {
              this.password = password;
          }
      }
      
    3. 定义后置处理器

      import org.springframework.beans.BeansException;
      import org.springframework.beans.factory.config.BeanPostProcessor;
      import org.springframework.stereotype.Component;
      
      @Component
      public class BeanPostProcessorConfig implements BeanPostProcessor {
      
          @Override
          public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
          	// 这是判断只对我们感兴趣的接口做处理
              if (bean instanceof TestBeanPostProcessorInterface) {
              	// 打印处理前password的值
                  String password = ((TestBeanPostProcessorInterface) bean).getPassword();
                  System.out.println(String.format("handler beanName: %s, password: %s", beanName, password));
              }
              return bean;
          }
      
          @Override
          public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
          	// 这是判断只对我们感兴趣的接口做处理
              if (bean instanceof TestBeanPostProcessorInterface) {
              	// 重新设置password的值
                  ((TestBeanPostProcessorInterface) bean).setPassword("********");
              }
              return bean;
          }
      }
      
      
    4. 编写测试类

      import org.junit.Test;
      import org.junit.runner.RunWith;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.boot.test.context.SpringBootTest;
      import org.springframework.test.context.junit4.SpringRunner;
      
      @RunWith(SpringRunner.class)
      @SpringBootTest
      public class BeanPostProcessorTest {
      
          @Autowired
          private UserInfoVO userInfoVO;
      
          @Test
          public void test() {
              System.out.println(userInfoVO.getPassword());
          }
      }
      
      
    5. 执行日志

      我们看到 userInfoVO类的password 参数被替换成了********

        .   ____          _            __ _ _
       /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
      ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
       \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
        '  |____| .__|_| |_|_| |_\__, | / / / /
       =========|_|==============|___/=/_/_/_/
       :: Spring Boot ::        (v2.2.0.RELEASE)
      
      2020-06-01 13:43:24.952  INFO 11432 --- [           main] c.e.d.c.spring.BeanPostProcessorTest     : Starting BeanPostProcessorTest on PC with PID 11432 (started by ASUS in E:\workspace\demo)
      2020-06-01 13:43:24.954  INFO 11432 --- [           main] c.e.d.c.spring.BeanPostProcessorTest     : No active profile set, falling back to default profiles: default
      2020-06-01 13:43:25.708  INFO 11432 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
      2020-06-01 13:43:25.711  INFO 11432 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data repositories in DEFAULT mode.
      2020-06-01 13:43:25.783  INFO 11432 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 46ms. Found 0 repository interfaces.
      handler beanName : userInfoVO, password : password
      2020-06-01 13:43:27.063  INFO 11432 --- [           main] c.e.d.c.spring.BeanPostProcessorTest     : Started BeanPostProcessorTest in 2.857 seconds (JVM running for 4.225)
      
      ********
      
      
      
      Process finished with exit code 0
      

    后置处理器加载解析

    • 这个是在创建applicationContext过程中,从抽象类AbstractApplicationContextrefresh方法开始,去除注释和日志,我们来看看源码
      @Override
      	public void refresh() throws BeansException, IllegalStateException {
      		synchronized (this.startupShutdownMonitor) {
      			
      			prepareRefresh();
      			
      			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
      			
      			prepareBeanFactory(beanFactory);
      
      			try {
      				postProcessBeanFactory(beanFactory);
      				
      				invokeBeanFactoryPostProcessors(beanFactory);
      				// 注册后置处理器
      				registerBeanPostProcessors(beanFactory);
      				
      				initMessageSource();
      				
      				initApplicationEventMulticaster();
      				
      				onRefresh();
      				
      				registerListeners();
      				
      				finishBeanFactoryInitialization(beanFactory);
      		
      				finishRefresh();
      			} catch (BeansException ex) {
      				
      				destroyBeans();
      				
      				cancelRefresh(ex);
      				
      				throw ex;
      			} finally {
      				resetCommonCaches();
      			}
      		}
      	}
      
      

      这里我们只关心registerBeanPostProcessors方法

    registerBeanPostProcessors注册拦截bean创建的后置处理器

    • 源码

      protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
      	PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
      }
      
      public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
      	// 获取所有实现了BeanPostProcessor接口的beanName
      	String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
      
      	// 计算一个bean最终应该会被实现了BeanPostProcessor接口处理的数量
      	int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
      	// 添加一个后置处理器,放在后面说明
      	beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
      
      	// 保存实现了优先排序接口(PriorityOrdered)的类
      	List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
      	// 保存实现了MergedBeanDefinitionPostProcessor接口的类,可以理解为spring内部类
      	List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
      	// 保存实现了排序接口(Ordered)的类
      	List<String> orderedPostProcessorNames = new ArrayList<>();
      	// 保存未实现任何排序接口的类
      	List<String> nonOrderedPostProcessorNames = new ArrayList<>();
      
      	for (String ppName : postProcessorNames) {
      		// 判断是否实现了PriorityOrdered接口
      		if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
      			// 获取并实例化bean
      			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      			priorityOrderedPostProcessors.add(pp);
      			// 可以理解为判断是否spring框架内部使用的实现类
      			if (pp instanceof MergedBeanDefinitionPostProcessor) {
      				internalPostProcessors.add(pp);
      			}
      		}
      		// 判断是否实现了Ordered接口
      		else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
      			orderedPostProcessorNames.add(ppName);
      		}
      		// 未实现排序接口的保存到nonOrderedPostProcessorNames集合
      		else {
      			nonOrderedPostProcessorNames.add(ppName);
      		}
      	}
      
      	// 进行排序后优先注册
      	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
      	registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
      
      	// 处理实现了Ordered排序接口的BeanPostProcessors实现类
      	List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
      	for (String ppName : orderedPostProcessorNames) {
      		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      		orderedPostProcessors.add(pp);
      		// 可以理解为判断是否框架内部使用的实现类
      		if (pp instanceof MergedBeanDefinitionPostProcessor) {
      			internalPostProcessors.add(pp);
      		}
      	}
      	// 进行排序后优先注册
      	sortPostProcessors(orderedPostProcessors, beanFactory);
      	registerBeanPostProcessors(beanFactory, orderedPostProcessors);
      
      	// 处理无排序的BeanPostProcessors实现类
      	List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
      	for (String ppName : nonOrderedPostProcessorNames) {
      		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      		nonOrderedPostProcessors.add(pp);
      		// 可以理解为判断是否spring框架内部使用的实现类
      		if (pp instanceof MergedBeanDefinitionPostProcessor) {
      			internalPostProcessors.add(pp);
      		}
      	}
      	// 无排序直接注册
      	registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
      
      	// 对内部类的排序
      	sortPostProcessors(internalPostProcessors, beanFactory);
      	// 重新注册内部类,作用是将内部类的注册放到最后
      	registerBeanPostProcessors(beanFactory, internalPostProcessors);
      
      	// 添加一个后置处理器,放在后面说明
      	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
      }
      

      注册过程还是比较简单的,我们看到,在注册过程中还创建了两个后置处理器BeanPostProcessorCheckerApplicationListenerDetector,这个在后面分析作用
      后置处理器的注册已经完成了,接下来我们看一下他的调用过程

    后置处理器的调用

    1. bean实例化前、后的处理调用过程

      跳过bean实例化过程,直接看一下初始化bean

      protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
      	// 判断是否启用了java安全管理器,正常情况下是null的,除非手动设置打开安全管理器
      	if (System.getSecurityManager() != null) {
      		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
      			invokeAwareMethods(beanName, bean);
      			return null;
      		}, getAccessControlContext());
      	}
      	else {
      		// 进行BeanNameAware、BeanClassLoaderAware和BeanFactoryAware感知注入
      		invokeAwareMethods(beanName, bean);
      	}
      
      	Object wrappedBean = bean;
      	// 判断是否合成bean,默认 synthetic = false,则!mbd.isSynthetic() = true
      	if (mbd == null || !mbd.isSynthetic()) {
      		// 调用前置处理器
      		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
      	}
      
      	try {
      		// 如果实现了InitializingBean接口,则调用afterPropertiesSet方法
      		invokeInitMethods(beanName, wrappedBean, mbd);
      	}
      	catch (Throwable ex) {
      		throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex);
      	}
      	
      	if (mbd == null || !mbd.isSynthetic()) {
      		// 调用后置处理器
      		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
      	}
      
      	return wrappedBean;
      }
      
      @Override
      public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
      		throws BeansException {
      
      	Object result = existingBean;
      	// 遍历处理器
      	for (BeanPostProcessor processor : getBeanPostProcessors()) {
      		// 执行前置处理器
      		Object current = processor.postProcessBeforeInitialization(result, beanName);
      		if (current == null) {
      			return result;
      		}
      		result = current;
      	}
      	return result;
      }
      
      @Override
      public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
      		throws BeansException {
      
      	Object result = existingBean;
      	// 遍历处理器
      	for (BeanPostProcessor processor : getBeanPostProcessors()) {
      		// 执行后置处理器
      		Object current = processor.postProcessAfterInitialization(result, beanName);
      		if (current == null) {
      			return result;
      		}
      		result = current;
      	}
      	return result;
      }
      

    举例谈谈spring内部实现了BeanPostProcessor接口的类

    1. BeanPostProcessorChecker用于检查是否存在不会被所有后置处理器处理的bean

      什么情况下会出现这个问题呢,首先我们要知道两件事情,然后看一下注册流程图
      1、单例bean只会实例化一次
      2、bean实例化的前后都会被后置处理器处理
      流程图:在这里插入图片描述
      综上我们可以看到在实例化后置处理器时会去实例化他的依赖bean,实例化依赖bean时又会执行后置处理器,但是此时的后置处理器并没有全部注册完成,所以这个依赖bean不会被还没实例化的后置处理器处理到

      我们看看spring是怎么实现BeanPostProcessorChecker的

      private static final class BeanPostProcessorChecker implements BeanPostProcessor {
      
      	private static final Log logger = LogFactory.getLog(BeanPostProcessorChecker.class);
      
      	private final ConfigurableListableBeanFactory beanFactory;
      
      	private final int beanPostProcessorTargetCount;
      
      	public BeanPostProcessorChecker(ConfigurableListableBeanFactory beanFactory, int beanPostProcessorTargetCount) {
      		this.beanFactory = beanFactory;
      		this.beanPostProcessorTargetCount = beanPostProcessorTargetCount;
      	}
      
      	@Override
      	public Object postProcessBeforeInitialization(Object bean, String beanName) {
      		return bean;
      	}
      
      	@Override
      	public Object postProcessAfterInitialization(Object bean, String beanName) {
      		// 1、bean不是后置处理器,2、不是内部bean,3、此时注册的后置处理器小于计算的总后置处理器
      		if (!(bean instanceof BeanPostProcessor) && !isInfrastructureBean(beanName) && this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount) {
      			// 打印日志
      			if (logger.isInfoEnabled()) {
      				logger.info("Bean '" + beanName + "' of type [" + bean.getClass().getName() +
      						"] is not eligible for getting processed by all BeanPostProcessors " +
      						"(for example: not eligible for auto-proxying)");
      			}
      		}
      		return bean;
      	}
      
      	private boolean isInfrastructureBean(@Nullable String beanName) {
      		if (beanName != null && this.beanFactory.containsBeanDefinition(beanName)) {
      			BeanDefinition bd = this.beanFactory.getBeanDefinition(beanName);
      			// RootBeanDefinition.ROLE_INFRASTRUCTURE = 2,标记为完全内部使用的bean
      			return (bd.getRole() == RootBeanDefinition.ROLE_INFRASTRUCTURE);
      		}
      		return false;
      	}
      }
      

      如果存在这种情况则会打印一行日志
      logger.info(“Bean '” + beanName + “’ of type [” + bean.getClass().getName() +
      "] is not eligible for getting processed by all BeanPostProcessors " +
      “(for example: not eligible for auto-proxying)”);

    2. ApplicationListenerDetector用于管理监听器

      ApplicationListenerDetector主要做两件事
      1、bean实例化时如果这个bean是监听器且是单例模式的则在广播中注册这个监听器
      2、bean销毁时判断如果是监听器则在广播中移除这个监听器

    • 附上源码

      class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor {
      
      	private static final Log logger = LogFactory.getLog(ApplicationListenerDetector.class);
      
      	private final transient AbstractApplicationContext applicationContext;
      
      	private final transient Map<String, Boolean> singletonNames = new ConcurrentHashMap<>(256);
      
      	public ApplicationListenerDetector(AbstractApplicationContext applicationContext) {
      		this.applicationContext = applicationContext;
      	}
      
      	@Override
      	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
      		this.singletonNames.put(beanName, beanDefinition.isSingleton());
      	}
      	@Override
      	public Object postProcessBeforeInitialization(Object bean, String beanName) {
      		return bean;
      	}
      
      	@Override
      	public Object postProcessAfterInitialization(Object bean, String beanName) {
      		if (bean instanceof ApplicationListener) {
      			// potentially not detected as a listener by getBeanNamesForType retrieval
      			Boolean flag = this.singletonNames.get(beanName);
      			if (Boolean.TRUE.equals(flag)) {
      				// singleton bean (top-level or inner): register on the fly
      				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;
      	}
      
      	@Override
      	public void postProcessBeforeDestruction(Object bean, String beanName) {
      		if (bean instanceof ApplicationListener) {
      			try {
      				ApplicationEventMulticaster multicaster = this.applicationContext.getApplicationEventMulticaster();
      				multicaster.removeApplicationListener((ApplicationListener<?>) bean);
      				multicaster.removeApplicationListenerBean(beanName);
      			}
      			catch (IllegalStateException ex) {
      				// ApplicationEventMulticaster not initialized yet - no need to remove a listener
      			}
      		}
      	}
      
      	@Override
      	public boolean requiresDestruction(Object bean) {
      		return (bean instanceof ApplicationListener);
      	}
      
      
      	@Override
      	public boolean equals(@Nullable Object other) {
      		return (this == other || (other instanceof ApplicationListenerDetector &&
      				this.applicationContext == ((ApplicationListenerDetector) other).applicationContext));
      	}
      
      	@Override
      	public int hashCode() {
      		return ObjectUtils.nullSafeHashCode(this.applicationContext);
      	}
      }
      
    • 注意在移除监听器时会清空整个监听器缓存

      @Override
      public void removeApplicationListener(ApplicationListener<?> listener) {
      	synchronized (this.retrievalMutex) {
      		this.defaultRetriever.applicationListeners.remove(listener);
      		// 清空监听器缓存
      		this.retrieverCache.clear();
      	}
      }
      
      @Override
      public void removeApplicationListenerBean(String listenerBeanName) {
      	synchronized (this.retrievalMutex) {
      		this.defaultRetriever.applicationListenerBeans.remove(listenerBeanName);
      		// 清空监听器缓存
      		this.retrieverCache.clear();
      	}
      }
      
    1. ApplicationContextAwareProcessor用于实现感知

      该后置处理器会对实现了EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware接口的bean注入对应的实例

    • 源码很简单
      class ApplicationContextAwareProcessor implements BeanPostProcessor {
      
      	private final ConfigurableApplicationContext applicationContext;
      
      	private final StringValueResolver embeddedValueResolver;
      
      
      	/**
      	 * Create a new ApplicationContextAwareProcessor for the given context.
      	 */
      	public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
      		this.applicationContext = applicationContext;
      		this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
      	}
      
      
      	@Override
      	@Nullable
      	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
      		// 判断这个bean是否实现了这些接口
      		if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
      				bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
      				bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
      			return bean;
      		}
      
      		AccessControlContext acc = null;
      
      		if (System.getSecurityManager() != null) {
      			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
      		}
      
      		if (acc != null) {
      			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
      				invokeAwareInterfaces(bean);
      				return null;
      			}, acc);
      		}
      		else {
      			invokeAwareInterfaces(bean);
      		}
      
      		return bean;
      	}
      	
      	// 注入响应的实例
      	private void invokeAwareInterfaces(Object bean) {
      		if (bean instanceof EnvironmentAware) {
      			((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
      		}
      		if (bean instanceof EmbeddedValueResolverAware) {
      			((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
      		}
      		if (bean instanceof ResourceLoaderAware) {
      			((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
      		}
      		if (bean instanceof ApplicationEventPublisherAware) {
      			((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
      		}
      		if (bean instanceof MessageSourceAware) {
      			((MessageSourceAware) bean).setMessageSource(this.applicationContext);
      		}
      		if (bean instanceof ApplicationContextAware) {
      			((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
      		}
      	}
      
      }
      
    1. AutowiredAnnotationBeanPostProcessor 增加对Autowired注解的支持

    2. CommonAnnotationBeanPostProcessor 负责解析@Resource、@WebServiceRef、@EJB注解

    3. ConfigurationClassPostProcessor 负责解析@Configuration、@PropertySource、@ComponentScan、@Import、@ImportResource、@Bean注解

    4. 还有很多。。。

    总结

    1. 可实现PriorityOrdered或Ordered接口定义后置处理器执行顺序
    2. 后置处理器A存在依赖bean的情况下,这个bean将无法被A及优先级低于A的处理器处理
    3. @Bean、@ComponentScan、@Import、@Resource等实用注解是通过后置处理器处理的
    4. bean初始化时先进行BeanNameAware、BeanClassLoaderAware和BeanFactoryAware感知注入,再执行前置处理,然后对实现了InitializingBean接口的方法afterPropertiesSet进行初始化,最后执行后置处理
    展开全文
  • Spring Bean后置处理器

    2019-03-25 16:41:00
    Bean 后置处理器允许在调用初始化方法前后对 Bean 进行额外的处理。 BeanPostProcessor接口定义回调方法,你可以实现该方法来提供自己的实例化逻辑,依赖解析逻辑等。你也可以在 Spring 容器通过插入一个或多个 ...

    本例子源于:W3CSchool,在此作记录

    Bean 后置处理器允许在调用初始化方法前后对 Bean 进行额外的处理。

    BeanPostProcessor 接口定义回调方法,你可以实现该方法来提供自己的实例化逻辑,依赖解析逻辑等。你也可以在 Spring 容器通过插入一个或多个 BeanPostProcessor 的实现来完成实例化,配置和初始化一个bean之后实现一些自定义逻辑回调方法。

    你可以配置多个 BeanPostProcessor 接口,通过设置 BeanPostProcessor 实现的 Ordered 接口提供的 order 属性来控制这些 BeanPostProcessor 接口的执行顺序。

    BeanPostProcessor 可以对 bean(或对象)实例进行操作,这意味着 Spring IoC 容器实例化一个 bean 实例,然后 BeanPostProcessor 接口进行它们的工作。

    ApplicationContext 会自动检测由 BeanPostProcessor 接口的实现定义的 bean,注册这些 bean 为后置处理器,然后通过在容器中创建 bean,在适当的时候调用它

    在你自定义的的BeanPostProcessor 接口实现类中,要实现以下的两个抽象方法BeanPostProcessor.postProcessBeforeInitialization(Object, String) 和BeanPostProcessor.postProcessAfterInitialization(Object, String) 和,注意命名要准确

    否则会出现: “ The type InitHelloWorld must implement the inherited abstract method BeanPostProcessor.postProcessBeforeInitialization(Object, String) ”之类的错误

    相对于上个例子,在原来的基础上新增一个BeanPostProcessor 接口实现类,在xml配置文件中添加该实现类对应的bean

    BeanPostProcessor 接口实现类如下:

    package com.how2java.w3cschool.beanlife;
    
    import org.springframework.beans.factory.config.BeanPostProcessor;
    
    public class InitHelloWorld implements BeanPostProcessor{
        public Object postProcessBeforeInitialization(Object bean,String beanName) {
            System.out.println("BeforeInitialization:"+beanName);
            return bean;  // you can return any other object as well
        }
        
        public Object postProcessAfterInitialization(Object bean,String beanName) {
            System.out.println("AfterInitialization:"+beanName);
            return bean;  // you can return any other object as well
        }
    }

    xml配置文件新增如下内容:

    <bean class = "com.how2java.w3cschool.beanlife.InitHelloWorld"></bean>

    输出的结果如下:

     

    转载于:https://www.cnblogs.com/Guhongying/p/10594631.html

    展开全文
  • bean后置处理器的作用:Bean后置处理器允许在调用初始化方法前后对Bean进行额外的处理。 1、创建bean后置处理器: 先创建一个类实现BeanPostProcessor接口,并具体提供: postProcessBeforeInitialization(Object...

    bean后置处理器的作用:Bean后置处理器允许在调用初始化方法前后对Bean进行额外的处理。

    1、创建bean后置处理器:

    先创建一个类实现BeanPostProcessor接口,并具体提供:

    postProcessBeforeInitialization(Object bean, String beanName)(init-method之前被调用)

    postProcessAfterInitialization(Object bean, String beanName)(init-method之后被调用)两个方法的具体实现。

    2、配置bean的后置处理器

    不需要配置bean的id,只需要指定class属性,IOC容器能自动识别bean后置处理器。

    注意:

    由于bean后置处理器是对IOC容器中的所有bean进行处理,所以可以在BeanPostProcessor的子类(bean后置处理器)中做一些判断,实现对具体某个bean的处理。

    展开全文
  • BeanPostProcessor是一个接口,用于在bean初始化之前和之后调用。(在bean属性赋值之后) 需要实现其中的2个方法 @Component public class MyBeanPostProcessor implements BeanPostProcessor { @Override public ...
  • Bean的声明离设置init-method和destroy-method属性,为Bean指定初始化和销毁方法。 1. 通过构造器或者工厂方法创建Bean实例 2. 为Bean的属性设置值和对其他Bean的引用 3. 调用Bean的初始化方法 4. 使用Bean 5. ...
  • Spring Bean 后置处理器BeanPostProcessor Spring 提供一种机制,只要实现此接口BeanPostProcessor,并将实现类提供给spring容器,spring容器将自动执行,在初始化方法前执行before(),在初始化方法后执行after() ...
  • spring-创建 Bean 后置处理器

    千次阅读 2017-04-14 17:22:57
    Bean 后置处理器允许在调用初始化方法前后对 Bean 进行额外的处理. Bean 后置处理器对 IOC 容器里的所有 Bean 实例逐一处理, 而非单一实例. 其典型应用是: 检查 Bean 属性的正确性或根据特定的标准更改 Bean 的属性....
  • 引言 Spring在我们目前的开发中基本上必不可少...bean后置处理器 其中Bean工厂后置处理器就是本节要讲的,它们会在Spring启动过程中,在实例化bean之前执行,它们主要用来扫描出后续需要进行实例化的bean,并注册成Bea
  • 主要介绍了Spring中的后置处理器BeanPostProcessor详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 版权声明:本文为 小异常 原创文章,非商用自由转载-保持署名-注明出处,... Bean后置处理器 是在实例化 Bean 之后的处理器,即当 Spring IOC容器 实例化 Bean 之后进行的增强的处理。    实现了 BeanPostPro...
  • Bean 后置处理器

    2018-04-13 14:22:42
    IOC容器自动识别后置处理器InitBeforBean 改bean实现BeanFactoryPostProcessor 该接口,更改 BeanLife bean的属性值和作用域@Test public void valueTest(){ ApplicationContext context = new ...
  • } 通过构造函数可以大概猜测该后置处理器的作用。 实现方法分析 由于CommonAnnotationBeanPostProcessor继承的InitDestroyAnnotationBeanPostProcessor也是具体类,且提供了很多逻辑,这里先分析...
  • 五、bean工厂后置处理器 5.1、源码解析 refresh()方法比较重要的代码是上篇文章标注的第5条和第11条代码,本次先解析第5行的代码invokeBeanFactoryPostProcessors,执行bean工厂后置处理器。 点进...
  • Bean后置处理器允许在调用初始化方法前后对Bean进行额外的处理,Bean后置处理器对IOC容器的所有bean实例逐一处理,而非单一实例。 我们可以定义一个或多个BeanPostProcessor接口实现类,然后注册到Spring IOC容器中...
  • Spring Bean后置处理器解析 一、postProcessBeforeInstantiation 二、determineCandidateConstructors 三、postProcessMergedBeanDefinition 四、getEarlyBeanReference 五、postProcessAfterInstantiation 六...
  • bean后置处理器 : 对IOC容器中所有的bean都起作用. */ public class MyBeanPostProcessor implements BeanPostProcessor { /** 在bean的生命周期的初始化方法之前执行 Object bean: 正在被创建的bean对象. String...
  • spring bean后置处理器作用
  • BeanPostProcessor接口 bean后置处理器实现功能主要是 可以在bean初始化之前和之后做增强处理。自定义MyBeanProcessor实现BeanPostProcessor接口,重写里面的postProcessBeforeInitialization和...
  • Spring BeanFactory后置处理器详解之配置类解析过程BeanFactoryPostProcessor实现方式BeanFactory后置处理器源码分析invokeBeanFactoryPostProcessors分析 BeanFactoryPostProcessor BeanFactoryPostProcessor是...
  • Spring Bean前置后置处理器的使用

    万次阅读 2018-09-24 21:17:11
    Spirng中BeanPostProcessor和InstantiationAwareBeanPostProcessorAdapter两个接口都可以实现对bean前置后置处理的效果,那这次先讲解一下BeanPostProcessor处理器的使用 先看一下BeanPostProcessor接口的源码,它...
  • Spring Bean 后置处理器

    2018-08-11 14:10:29
    转载自 Spring Bean 后置处理器 Spring——Bean 后置处理器 BeanPostProcessor 接口定义回调方法,你可以实现该方法来提供自己的实例化逻辑,依赖解析逻辑等。你也可以在 Spring 容器通过插入一个或多个 ...
  • Bean 后置处理器允许在调用初始化方法前后对 Bean 进行额外的处理. Bean 后置处理器对 IOC 容器里的所有 Bean 实例逐一处理, 而非单一实例. 其典型应用是: 检查 Bean 属性的正确性或根据特定的标准更改 Bean 的属性....
  • 一、接口: public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { ... //如果返回了bean实例, 则会替代原来正常通过target bean生成的bean的流程 //典型的例如aop返回pr...
  • Bean后置处理器详解: Spring当中的后置处理器是Spring体用的一个扩展点,开发者只要去实现,Spring当中的BeanPostProcessor接口,那么就能插手SpringBean实例化的一个过程,怎么插手呢? 它是在我们bean被放到...
  • BeanPostProcessor:是一个接口,bean后置处理器(实际是在bean的初始化前后执行操作) public class MyBeanPostProcessor implements BeanPostProcessor{ /** * bean是容器调用构造器创建的实例 * beanName...
  • spring的启动过程04-bean后置处理器

    千次阅读 2016-12-30 13:55:02
    这里spring就想到了采用注册bean处理器的方式处理个性化需求,该种方式类似于intercept功能,又类似于AOP横向切面的概念,因为它同样提供前置处理逻辑及后置处理逻辑,下面具体分析下这种方式的实现过程。...
  • 后置处理器允许在调用初始化方法前后对 Bean 进行额外的处理 . 一:BeanFactory 若使用 BeanFactory ,则必须要显示的调用其 addBeanPostProcessor() 方法进行注册,参数为 BeanPostProcessor ...

空空如也

空空如也

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

bean的后置处理器