spring 核心后置处理器-BeanDefinitionRegistryPostProcessor

前面文章中介绍过几种将object->bean的方式

那么我们这个后置处理器一样可以实现,我们看代码

public class User {

	public User(){
		System.out.println("init-user");
	};
}

@Component
public class TestBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		RootBeanDefinition userBean = new RootBeanDefinition(User.class);
		//新增Bean定义
		registry.registerBeanDefinition("userBo", userBean);
	}

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userBo");
		beanDefinition.setScope("prototype");
		System.out.println("Scope:"+beanDefinition.getScope());
	}
}

重写的这个方法很眼熟postProcessBeanFactory前面的博客已经证明过了。就主要看第一个

postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)这个方法中传进来了一个bd注册器

而RootBeanDefinition是BeanDefinition的一个字类,在spring内部的bean都是通过该对象将object root 成一个bean

那么既然传进来了一个bd注册器。我们可不可以将一个代理类root进去呢

我们接着上面又一篇将接口的变为bean的帖子继续测试

我们将上一篇的博客改一下,将这个接口ImportBeanDefinitionRegistrar改成我们的这个接口BeanDefinitionRegistryPostProcessor 

请看代码

public class TestBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		//扫描TestMapper这个接口
		BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(TestMapper.class);
		GenericBeanDefinition beanDefinition =(GenericBeanDefinition) builder.getBeanDefinition();
		beanDefinition.setBeanClass(TestFactoryBean.class);
		beanDefinition.getConstructorArgumentValues().addGenericArgumentValue("org.springframework.spring.mybatis.mapper.TestMapper");
beanDefinition.setScope("singleton");//定义作用域
		registry.registerBeanDefinition("testMapper",beanDefinition);
	}

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		BeanDefinition beanDefinition = beanFactory.getBeanDefinition("testMapper");
		System.out.println("setScope before:"+beanDefinition.getScope());//很尴尬这儿也是空的,因为是代理对象的原因吗?/需要先定义作用域,已解决
		beanDefinition.setScope("prototype");
		System.out.println("setScope after:"+beanDefinition.getScope());
	}
}

自定义注解更换配置,换成我们的当前接口

@Retention(RetentionPolicy.RUNTIME)
//@Import(TestImportBeanDifinitionRegistrar.class)
@Import(TestBeanDefinitionRegistryPostProcessor.class)
public @interface TestScanMapper {
}

配置类添加开启注解@TestScanMapper

测试

public class MainDemo {
		public static void main(String[] args) {
			AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
			TestMapper bean =(TestMapper) ac.getBean("testMapper");
			System.out.println("TestMapper hashcode():"+bean.hashCode());//很尴尬是空的
		}

}

程序很友好,跑起来没报错............

那么我们这个接口不仅能改变beanFactory中bean的原注解属性,还可将对象交给spring管理,还能将代理对象交给spring管理

猜你喜欢

转载自blog.csdn.net/qq_38108719/article/details/100593855
今日推荐