建设工程资料下载网站,基于站点的网络营销方法,斗蟋蟀网站建设,绍兴建站模板系统目录前言Spring的后置处理器Bean工厂后置处理器Bean后置处理器自定义Component实现注解开发前言
看这篇文章之前#xff0c;需要了解Bean创建的过程#xff0c;本篇文章是接着bean创建的基本流程的续写 Bean创建的基本过程#xff1a;http://t.csdn.cn/1lK2d Spring的后置处…
目录前言Spring的后置处理器Bean工厂后置处理器Bean后置处理器自定义Component实现注解开发前言
看这篇文章之前需要了解Bean创建的过程本篇文章是接着bean创建的基本流程的续写 Bean创建的基本过程http://t.csdn.cn/1lK2d Spring的后置处理器
熟悉Bean创建的基本流程是前提
Spring的后处理器是Spring对外开发的重要扩展点允许我们介入到Bean的整个实例化流程中来以达到动态注册BeanDefinition动态修改BeanDefinition以及动态修改Bean的作用。Spring主要有两种后处理器
BeanFactoryPostProcessorBean工厂后处理器在BeanDefinitionMap填充完毕Bean实例化之前执行BeanPostProcessorBean后处理器一般在Bean实例化之后填充到单例池singletonObjects之前执行 那Spring的后置处理器有什么用处呢 不知道你看到它可以动态注册BeanDefinition时有什么想法对你想的没错注解开发原理中就是用Spring的后置处理器来动态创建Bean对象的别眨眼接下来就时见证奇迹的时刻 Bean工厂后置处理器
Bean工厂后处理器在BeanDefinitionMap填充完毕Bean实例化之前执行也就是当把xml中所有bean配置信息封装成BeanDefinition对象装到BeanDefinitionMap集合后但还没有反射创建bean对象时再往map中注册BeanDefinition对象后续反射就会创建出新的xml中未定义的对象 Bean工厂后处理器 – BeanFactoryPostProcessor BeanFactoryPostProcessor是一个接口规范实现了该接口的类只要交由Spring容器管理的话在BeanDefinitionMap填充完毕后Spring就会回调该接口的方法用于对BeanDefinition注册和修改的功能。
所以它的使用分以下几步
创建一个处理器类实现BeanFactoryPostProcessor接口重写BeanFactoryPostProcessor的方法交给Spring容器管理配置到xml中或加注解 使用方式如下 由于BeanDefinition是接口我们要new 一个BeanDefinition对象就要new 它的一个实现类RootBeanDefinition对象 其中需要强转为DefaultListableBeanFactory是因为ConfigurableListableBeanFactory的对象无法把beanDefinition注册到map中BeanDefinitionMap是DefaultListableBeanFactory中定义的集合而DefaultListableBeanFactory又是实现了ConfigurableListableBeanFactory的接口所以强转一下。 不得不说这个源码自己也需要多看不然这些接口名类名是什么继承了什么有什么关键成员变量都不清楚看这些调用关系自然就云里雾里 Spring 提供了一个BeanFactoryPostProcessor的子接口BeanDefinitionRegistryPostProcessor专门用于注册BeanDefinition操作
public class MyBeanFactoryPostProcessor2 implements BeanDefinitionRegistryPostProcessor {//这个方法是BeanFactoryPostProcessor接口的方法重写一下就不用管了Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {}Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {BeanDefinition beanDefinition new RootBeanDefinition();beanDefinition.setBeanClassName(com.dao.UserDaoImpl);//要创建的bean的位置//注册beanDefinitionbeanDefinitionRegistry.registerBeanDefinition(userDao,beanDefinition);}
}最后main方法中调用时
UserDao userDao applicationContext.getBean(UserDao.class)Bean后置处理器
Bean后处理器 – BeanPostProcessor
Bean被实例化后到最终缓存到名为singletonObjects单例池之前中间会经过Bean的初始化过程例如属性的填充、初始方法init的执行等其中有一个对外进行扩展的点BeanPostProcessor我们称为Bean后处理。跟上面的Bean工厂后处理器相似它也是一个接口实现了该接口并被容器管理的BeanPostProcessor会在流程节点上被Spring自动调用。 bean后处理器的使用步骤和bean工厂后处理器基本类似只是处理时机不一样bean工厂后处理器在填充map后实例化前bean后处理器在实例化后添加单例池前
创建后处理器类自己随便创建一个就行实现 BeanPostProcessor接口重写它的方法把后处理器类交由bean管理 BeanPostProcessor的接口定义如下模板
public interface BeanPostProcessor {Nullable//表示该方法可以不写//在属性注入完毕init初始化方法执行之前被回调default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}Nullable//在初始化方法执行之后被添加到单例池singletonObjects之前被回调default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}
}自定义Component实现注解开发
自定义MyComponent注解使用在类上使用包扫描器工具BaseClassScanUtils 完成指定包的类扫描自定义BeanFactoryPostProcessor完成注解MyComponent的解析解析后最终被Spring管理。注意实现BeanFactoryPostProcessor接口的类需要交由Spring管理
原理大概就是用包扫描工具类指定包及其子包下的类上加了自定义注解的类名获取并添加到一个map集合中然后遍历依次对它们进行包装成一个个BeanDefinition对象然后再它们注册到BeanDefinitionMap集合中后续反射创建bean时这些注解添加的bean也会被创建。 public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {//指定要扫描的包String basePackage com;//调用扫描工具BaseClassScanUtils扫描指定包及其子包下的MyComponentMapString, Class myComponentClassMap BaseClassScanUtils.scanMyComponentAnnotation(basePackage);//遍历Map集合创建BeanDefinition对象进行注册myComponentClassMap.forEach((beanName,clazz)-{try {BeanDefinition beanDefinition new RootBeanDefinition();beanDefinition.setBeanClassName(clazz.getName());registry.registerBeanDefinition(beanName,beanDefinition);} catch (Exception e) {e.printStackTrace();}});}不得不说有那味了