前面文章中介紹過幾種將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管理