模拟实现解析@Bean注解

本文通过实例展示了如何模拟实现Spring框架中的@Bean注解解析过程,包括创建Bean1和Bean4,编写自定义BeanFactory后处理器,以及进行测试以确保Bean4和Bean5的初始化方法被正确调用。

准备一个Bean1

@ComponentScan({"com.ghc.springlearning.MyPostProcessors.components"})
@Configuration
public class Bean1 {
    @Bean(initMethod = "init")
    public Bean4 bean4(){
        return new Bean4();
    }
    @Bean
    public Bean5 bean5(){
        return new Bean5();
    }
}

Bean4

public class Bean4 {
    public void init(){
        System.out.println("bean4 初始化");
    }
}

编写自定义BeanFactory后处理器实现接口

public class AtBeanPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        DefaultListableBeanFactory beanFactory=(DefaultListableBeanFactory) configurableListableBeanFactory;
        CachingMetadataReaderFactory readerFactory = new CachingMetadataReaderFactory();
        try {
            //1.拿到MetadataReader
            MetadataReader metadataReader = readerFactory.getMetadataReader(new ClassPathResource("com/ghc/springlearning/MyPostProcessors/components/Bean1.class"));
            //2.拿到注解元数据--》拿到注解的方法
            Set<MethodMetadata> methods = metadataReader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
            for (MethodMetadata method : methods) {
                BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition();
                //工厂方法Bean,指定哪个方法,属于哪个对象
                //看@Bean有无设置其他属性,如初始化方法
                //获取方法加的注解属性,如initMethod
                String initMethod = method.getAnnotationAttributes(Bean.class.getName()).get("initMethod").toString();
                //如果initMethod不为空,说明有
                if(initMethod.length()>0){
                    //设置初始化方法
                    beanDefinitionBuilder.setInitMethodName(initMethod);
                }
                beanDefinitionBuilder.setFactoryMethodOnBean(method.getMethodName(),"bean1");
                //拿到beanDefinition
                AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
                beanFactory.registerBeanDefinition(method.getMethodName(),beanDefinition);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

将后处理器注册为Bean,测试代码:

public class Test {
    public static void main(String[] args) {
        GenericApplicationContext context = new GenericApplicationContext();
        context.registerBean("bean1",Bean1.class);
        context.registerBean(ComponentScanProcessor.class);
        context.registerBean(AtBeanPostProcessor.class);
        context.refresh();
        for (String name : context.getBeanDefinitionNames()) {
            System.out.println(name);
        }
    }
}

结果:

成功解析出了bean4,bean5 ,并且执行了bean4的初始化方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值