前面文章中介绍过几种将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管理