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管理

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章