自定义BeanPostProcessor实现注册beanDefinition(模拟实现mabatis scanmapper)

Spring源码导读

场景:模拟mabatis scanmapper 实现dao。读者可以拷贝我的代码进行跑一波替换一下,注意里面很多包路径需要替换。

 

写一个model

public class Model {

}

写一个仓储接口

@Repository
public interface ModelMapper {
    void insert(Model model);
}

使用工厂模式,这里只是模拟假装实现。

public class MapperFactoryBean implements FactoryBean {

    Class<?> proxyInstanceClass;

    public MapperFactoryBean(Class<?> proxyInstanceClass) {
       this.proxyInstanceClass = proxyInstanceClass;
    }



    @Override
    public Object getObject() throws Exception {
        return Proxy.newProxyInstance(proxyInstanceClass.getClassLoader(), new Class[]{proxyInstanceClass}, new ModelMapperInvocationHandler());
    }
    @Override
    public Class<?> getObjectType() {
        return proxyInstanceClass;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    class ModelMapperInvocationHandler implements InvocationHandler {

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

            System.out.println("get sql");
            System.out.println("get get link");
            System.out.println("execute sql");
            System.out.println("close link");

            return 0;
        }
    }
}

MapperScanPostProcessor 实现postProcessBeanDefinitionRegistry方法通过包扫描方式扫描Repository注解的接口,然后修改它的bean定义。

public class MapperScanPostProcessor implements BeanDefinitionRegistryPostProcessor {


    ApplicationContext applicationContext;

    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {

        MapScanner mapScanner = new MapScanner(registry);

        mapScanner.setResourceLoader(applicationContext);
        mapScanner.scan("com.jack.ascp.purchase.app.test.spring.beanfactorypostprocessor");
    }

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

    }

    class MapScanner extends ClassPathBeanDefinitionScanner {

        public MapScanner(BeanDefinitionRegistry registry) {
            super(registry);
        }

        @Override
        protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
            return beanDefinition.getMetadata().isInterface();
        }

        @Override
        protected void registerDefaultFilters() {
            this.addIncludeFilter(new AnnotationTypeFilter(Repository.class));
        }

        @Override
        protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
            Set<BeanDefinitionHolder>  beanDefinitionHolders = super.doScan(basePackages);
            for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) {
                BeanDefinition beanDefinition = beanDefinitionHolder.getBeanDefinition();
                String className = beanDefinition.getBeanClassName();
                TypedStringValue typedStringValue = new TypedStringValue(className);
                beanDefinition.setBeanClassName("com.jack.ascp.purchase.app.test.spring.beanfactorypostprocessor.MapperFactoryBean");
                beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(typedStringValue);
            }
            return beanDefinitionHolders;

        }
    }

}

再假装写一个service层

public class ModelService {
    private ModelMapper modelMapper;
//    public void setModelMapper(ModelMapper modelMapper) {
//        this.modelMapper = modelMapper;
//    }
    
    public ModelService(ModelMapper modelMapper) {
        this.modelMapper = modelMapper;
    }
    
    public void insert() {
        modelMapper.insert(new Model());
    }

}

我们的processor是可以处理多个mapper的 这里随便加一个demo

@Repository
public interface PersonMapper {
    int  update(Object o);
}

modelmapper.xml文件:

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        ">

    <!--<bean class="com.jack.ascp.purchase.app.test.spring.beanfactorypostprocessorstprocessor.MapperFactoryBean"/>-->
    <bean class="com.jack.ascp.purchase.app.test.spring.beanfactorypostprocessor.MapperScanPostProcessor" />
    <bean class="com.jack.ascp.purchase.app.test.spring.beanfactorypostprocessor.ModelService" autowire="constructor"/>

</beans>

测试代码:

public class PostProcessorApplication {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("modelmapper.xml");
        ModelMapper modelMapper = context.getBean(ModelMapper.class);
        modelMapper.insert(new Model());
        ModelService modelService = context.getBean(ModelService.class);
        modelService.insert();

        PersonMapper personMapper = context.getBean(PersonMapper.class);
        personMapper.update(new Object());

    }

}

结果

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值