beanPostProcessor: 插手bean实例化过程,实例化之后,工作在bean实例被放在spring的容器之前,例如@PostConstruct, AOP
BeanFactoryPostProcessor: 在bean实例化之前执行,针对beanfactory操作,进行类bd 管理操作,例如configclasspostprocesor对appfig进行cglib代理,生成代理类
BeanDefinitionRegistryPostProcessor:在BeanFactoryPostProcessor之前执行
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
.......................
例如configclasspostprocesor,扫描,处理import, @bean,解析,注册,判断配置类是否是full configuration
BeanFactoryPostProcessor有spring自带的,也有自定义的(需要手动applicationcontext.addBeanFactoryPostProcessor(beanFactoryPostProcessor)),
自定义的先执行,再执行spring自带,可以查看源码
ImportSelector : 引入类,返回string[],(类名是全限),然后将类转化为·bd, 动态添加bd(此bd是死的,无法修改,因为有class-->bd过程是由spring处理,给类名,spring帮你注册,程序员无法插手),也可以动态扫描
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{LmqService2.class.getName()};
}
}
ImportBeanDefinitionRegistrar:引入类,动态改变bd,意思是给你BeanDefinitionRegistry registry,你自己去注册,而ImportSelector 没有BeanDefinitionRegistry registry,相当于即使改变bd,但没registry,相当于没法注册改变得bd,也就是没法动态改变bd
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
/**
* 得到bd,或者类信息,这里对于接口类,假设实现创建代理对象,
*/
//这里先写死去为某个接口去创建动态代理对象,其实可以模拟扫描注解的接口,类似mybatis的mapperscan, UserMapper是个接口
// UserMapper userMapper= (UserMapper) Proxy.newProxyInstance(MainTest.class.getClassLoader(), new Class[]{UserMapper.class}, new InvocationHandler() {
// @Override
// public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// System.out.println("in proxy");
// return null;
// }
// });
// BeanDefinitionBuilder beanDefinitionBuilder= BeanDefinitionBuilder.genericBeanDefinition(userMapper.getClass()); //实际无法获取代理类信息,使用factorybean
BeanDefinitionBuilder beanDefinitionBuilder= BeanDefinitionBuilder.genericBeanDefinition(UserMapper.class);
GenericBeanDefinition beanDefinition= (GenericBeanDefinition) beanDefinitionBuilder.getBeanDefinition();
//为了传参数,可以给bd添加构造函数
beanDefinition.getConstructorArgumentValues().addGenericArgumentValue("com.lmq.dao.UserMapper");
beanDefinition.setBeanClass(MyFactoryBean.class); //MyFactoryBean不能加Componenrt注解
registry.registerBeanDefinition("userMapper",beanDefinition);
}
}