03-BeanFactoryPostProcessor

准备Bean

public class Bean1 {

    public void Bean1() {
        System.out.println("Bean1被Spring实例化");
    }

}

@Component
public class Bean2 {

    public void Bean2() {
        System.out.println("Bean2被Spring管理了");
    }

}

public class Bean3 {

    public void Bean3() {
        System.out.println("Bean3被Spring管理了");
    }

}

@Controller   // @Component派生注解
public class Controller1 {

    public void Controller1() {
        System.out.println("Controller1实例化被Spring管理了");
    }

}

public interface Mapper1 {
}

public interface Mapper2 {
}


@Configuration
@ComponentScan(basePackages = "com.you.meet.nice.test.web.spring.beanfactorypostprocessor.component")
public class Config {

    @Bean
    public Bean1 bean1() {
        return new Bean1();
    }

    @Bean
    public DataSource dataSource() {
        DataSourceProperties dataSourceProperties = new DataSourceProperties();
        dataSourceProperties.setUsername("root");
        dataSourceProperties.setPassword("root");
        dataSourceProperties.setUrl("jdbc:mysql://127.0.0.1:3306/base?useSSL=false&characterEncoding=utf-8&autoReconnect=true&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&useUnicode=true&autoReconnect=true&failOverReadOnly=false");
        return dataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
    }

    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        return sqlSessionFactoryBean;
    }

    /*@Bean
    public MapperFactoryBean<Mapper1> mapper1(SqlSessionFactory sqlSessionFactory){
        MapperFactoryBean<Mapper1> mapper1MapperFactoryBean = new MapperFactoryBean<>(Mapper1.class);
        mapper1MapperFactoryBean.setSqlSessionFactory(sqlSessionFactory);
        return mapper1MapperFactoryBean;
    }

    @Bean
    public MapperFactoryBean<Mapper2> mapper2(SqlSessionFactory sqlSessionFactory){
        MapperFactoryBean<Mapper2> mapper2MapperFactoryBean = new MapperFactoryBean<>(Mapper2.class);
        mapper2MapperFactoryBean.setSqlSessionFactory(sqlSessionFactory);
        return mapper2MapperFactoryBean;
    }*/

}

ConfigurationClassPostProcessor

// GenericApplicationContext无BeanFactory后置处理器
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("config", Config.class);
/**
 * 处理@ComponentScan @Bean  @Import @ImportResource 的后置处理器
 * 不加此处理器  当前Context中只有config这一个bean
 */
applicationContext.registerBean(ConfigurationClassPostProcessor.class);

// @MapperScan功能
applicationContext.registerBean(MapperScannerConfigurer.class, beanDefinition -> {
    beanDefinition.getPropertyValues().add("basePackage", "com.you.meet.nice.test.web.spring.beanfactorypostprocessor.mapper");
});

applicationContext.refresh();

for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
    System.out.println(beanDefinitionName);
}
applicationContext.close();

Spring如何完成@ComponentScan的

GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("config", Config.class);

ComponentScan componentScan = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);

if (Objects.nonNull(componentScan)) {
    CachingMetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory();
    BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
    DefaultListableBeanFactory defaultListableBeanFactory = applicationContext.getDefaultListableBeanFactory();
    for (String basePackage : componentScan.basePackages()) {
        //System.out.println(basePackage);
        // com.you.meet.nice.test.web.spring.beanfactorypostprocessor.component  -> classpath:com/you/meet/nice/test/web/spring/beanfactorypostprocessor/component/**/*.class
        String path = "classpath:" + basePackage.replace(".", "/") + "/**/*.class";
        //System.out.println(path);
        for (Resource resource : applicationContext.getResources(path)) {
            MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
            /*System.out.println("类名:"+ metadataReader.getClassMetadata().getClassName());
            System.out.println("是否有@Componenet注解:"+metadataReader.getAnnotationMetadata().hasAnnotation(Component.class.getName()));
            System.out.println("是否有@Componenet派生注解:"+metadataReader.getAnnotationMetadata().hasMetaAnnotation(Component.class.getName()));*/
            AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
            if (annotationMetadata.hasAnnotation(Component.class.getName()) ||
                    annotationMetadata.hasMetaAnnotation(Component.class.getName())) {
                AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(metadataReader.getClassMetadata().getClassName())
                        .getBeanDefinition();
                String beanName = beanNameGenerator.generateBeanName(beanDefinition, defaultListableBeanFactory);
                defaultListableBeanFactory.registerBeanDefinition(beanName, beanDefinition);
            }

        }
    }
}

for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
    System.out.println(beanDefinitionName);
}

自定义-MyComponentScanPostProcessor

public class MyComponentScanPostProcessor implements BeanDefinitionRegistryPostProcessor {

    @Override
    @SneakyThrows
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        //  正规写法应该获取所有@Configuration的类
        ComponentScan componentScan = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);

        if (Objects.nonNull(componentScan)) {
            CachingMetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory();
            BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
            PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();
            for (String basePackage : componentScan.basePackages()) {
                String path = "classpath:" + basePackage.replace(".", "/") + "/**/*.class";
                for (Resource resource : pathMatchingResourcePatternResolver.getResources(path)) {
                    MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
                    AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
                    if (annotationMetadata.hasAnnotation(Component.class.getName()) ||
                            annotationMetadata.hasMetaAnnotation(Component.class.getName())) {
                        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(metadataReader.getClassMetadata().getClassName())
                                .getBeanDefinition();
                        String beanName = beanNameGenerator.generateBeanName(beanDefinition, registry);
                        registry.registerBeanDefinition(beanName, beanDefinition);
                    }
                }
            }
        }
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

    }
}

测试

GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("config", Config.class);

applicationContext.registerBean(MyComponentScanPostProcessor.class);

applicationContext.refresh();

for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
    System.out.println(beanDefinitionName);
}

applicationContext.close();

Spring是如何完成@Bean

GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("config", Config.class);

CachingMetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory();
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(new ClassPathResource("com/you/meet/nice/test/web/spring/beanfactorypostprocessor/Config.class"));
Set<MethodMetadata> methods = metadataReader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
for (MethodMetadata method : methods) {
    String initMethod = method.getAnnotationAttributes(Bean.class.getName()).get("initMethod").toString();
//            System.out.println(method);
    BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition()
            .setFactoryMethodOnBean(method.getMethodName(), "config")
            // 方法参数值注入
            .setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
    if (StrUtil.isNotBlank(initMethod)) {
        beanDefinitionBuilder.setInitMethodName(initMethod);
    }
    // 一般@Bean的bean名字都是取方法名
    applicationContext.getDefaultListableBeanFactory().registerBeanDefinition(method.getMethodName(), beanDefinitionBuilder.getBeanDefinition());
}

applicationContext.refresh();

for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
    System.out.println(beanDefinitionName);
}

System.out.println(applicationContext.getBean(SqlSessionFactoryBean.class));

自定义-MyAtBeanPostProcessor

public class MyAtBeanPostProcessor implements BeanDefinitionRegistryPostProcessor {

    @SneakyThrows
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        CachingMetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory();
        MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(new ClassPathResource("com/you/meet/nice/test/web/spring/beanfactorypostprocessor/Config.class"));
        Set<MethodMetadata> methods = metadataReader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
        for (MethodMetadata method : methods) {
            String initMethod = method.getAnnotationAttributes(Bean.class.getName()).get("initMethod").toString();
//            System.out.println(method);
            BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition()
                    .setFactoryMethodOnBean(method.getMethodName(), "config")
                    // 方法参数值注入
                    .setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
            if (StrUtil.isNotBlank(initMethod)) {
                beanDefinitionBuilder.setInitMethodName(initMethod);
            }
            // 一般@Bean的bean名字都是取方法名
            registry.registerBeanDefinition(method.getMethodName(), beanDefinitionBuilder.getBeanDefinition());
        }
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

    }
}

测试

GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("config", Config.class);

applicationContext.registerBean(MyAtBeanPostProcessor.class);

applicationContext.refresh();

for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
    System.out.println(beanDefinitionName);
}

System.out.println(applicationContext.getBean(SqlSessionFactoryBean.class));

MapperFactoryBean

@Configuration
@ComponentScan(basePackages = "com.you.meet.nice.test.web.spring.beanfactorypostprocessor.component")
public class Config {

    @Bean
    public Bean1 bean1() {
        return new Bean1();
    }

    @Bean
    public DataSource dataSource() {
        DataSourceProperties dataSourceProperties = new DataSourceProperties();
        dataSourceProperties.setUsername("root");
        dataSourceProperties.setPassword("root");
        dataSourceProperties.setUrl("jdbc:mysql://127.0.0.1:3306/base?useSSL=false&characterEncoding=utf-8&autoReconnect=true&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&useUnicode=true&autoReconnect=true&failOverReadOnly=false");
        return dataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
    }

    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        return sqlSessionFactoryBean;
    }

    @Bean
    public MapperFactoryBean<Mapper1> mapper1(SqlSessionFactory sqlSessionFactory){
        MapperFactoryBean<Mapper1> mapper1MapperFactoryBean = new MapperFactoryBean<>(Mapper1.class);
        mapper1MapperFactoryBean.setSqlSessionFactory(sqlSessionFactory);
        return mapper1MapperFactoryBean;
    }

    @Bean
    public MapperFactoryBean<Mapper2> mapper2(SqlSessionFactory sqlSessionFactory){
        MapperFactoryBean<Mapper2> mapper2MapperFactoryBean = new MapperFactoryBean<>(Mapper2.class);
        mapper2MapperFactoryBean.setSqlSessionFactory(sqlSessionFactory);
        return mapper2MapperFactoryBean;
    }

}
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("config", Config.class);

applicationContext.registerBean(ConfigurationClassPostProcessor.class);

applicationContext.refresh();
for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
    System.out.println(beanDefinitionName);
}
applicationContext.close();

自定义-MyMapperPostProcessor

public class MyMapperPostProcessor implements BeanDefinitionRegistryPostProcessor {

    @SneakyThrows
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        Resource[] resources = new PathMatchingResourcePatternResolver().getResources("classpath:com/you/meet/nice/test/web/spring/beanfactorypostprocessor/mapper/**/*.class");
        CachingMetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory();
        AnnotationBeanNameGenerator annotationBeanNameGenerator = new AnnotationBeanNameGenerator();
        for (Resource resource : resources) {
            MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
            ClassMetadata classMetadata = metadataReader.getClassMetadata();
            if (classMetadata.isInterface()) {
                AbstractBeanDefinition mapperFactoryBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(MapperFactoryBean.class)
                        .addConstructorArgValue(classMetadata.getClassName())
                        .setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE)
                        .getBeanDefinition();
                /**
                 * 这里BeanName不能使用mapperFactoryBeanDefinition
                 * 因为同名Bean会被覆盖
                 * 这个mapperBeanDefinition不放入Bean容器  只是用来生成Bean名字
                 */
                AbstractBeanDefinition mapperBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(classMetadata.getClassName()).getBeanDefinition();
                String beanName = annotationBeanNameGenerator.generateBeanName(mapperBeanDefinition, registry);

                registry.registerBeanDefinition(beanName, mapperFactoryBeanDefinition);
            }
        }

    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

    }
}

测试

GenericApplicationContext applicationContext = new GenericApplicationContext();
// 注释Config类中的MapperFactoryBean
applicationContext.registerBean("config", Config.class);
applicationContext.registerBean(ConfigurationClassPostProcessor.class);

applicationContext.registerBean(MyMapperPostProcessor.class);

applicationContext.refresh();
for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
    System.out.println(beanDefinitionName);
}
applicationContext.close();
  • 13
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

层巅余落日

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值