Spring整合Mybatis

前提:

整合就是Mybatis利用Spring提供的类或者注解,创建对象。把对象注入到ioc容器中;

bean是java对象,而java对象不一定是bean对象;

右ioc容器(BeanFactory)生成管理的对象才是bean;

动态代理是Mybatis框架生成的、代理对象不在ioc容器中,所以代理对象无法自动注入到属性中;

我们整合的目的就是把代理对象存放在ioc容器中;

第一步:
 

//把注册beanDefinition这个类导入到ioc容器中
@Import({RegistrarBeanDefinition.class})
public class Config {
    
    //测试代码
    public static void main(String[] args) throws ClassNotFoundException {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);
        
        Bean01 user = applicationContext.getBean("bean01", Bean01.class);
        user.text();

#一个很重要的类factoryBean:这个类返回的对象会存放在ioc容器中(Spring-Mybatis就是用这个类进行整合的)

//这里没有@Component这个注解,还需要很多步骤
public class UserMapperFactoryBean implements FactoryBean {


    //这个class对象就是原来需要执行的那个类
    Class aClass;

    public UserMapperFactoryBean(Class aClass) {
        this.aClass = aClass;
    }

    @Override
    public Object getObject() throws Exception {

       //通过动态代理返回一个id为UserMapperFactoryBean 的object对象
       //在对象进行执行对象中的方法时,会执行动态代理生成的对象的方法
       Object object =  Proxy.newProxyInstance(UserMapperFactoryBean.class.getClassLoader(), new Class[]{aClass},
                new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("动态代理调用成功");
                System.out.println(method.getName());
                return 1;
            }
        });
        //返回的这个对象会存入到ioc容器中
        return object;
    }

    @Override
    public Class<?> getObjectType() {
       //设置返回对象的class类型,在@Autowired这个注解进行ByType注入的时候特别重要
        return aClass;
    }
}

#ImportBeanDefinitionRegistrar这个接口

spring看到一个类实现了ImportBeanDefinitionRegistrar并且重写了registerBeanDefinitions()方法会直接直接执行这个方法;

这个方法可以用来修改初始化Bean的BeanDefinition;

public class RegistrarBeanDefinition implements ImportBeanDefinitionRegistrar {
    //ImportBeanDefinition是用来注册BeanDefinition



    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        

        //这个就是我们说手写的MapperScan接口扫描器,扫描我们的mapper接口
        //扫描接口的目的就是为了把接口的class对象传入到FactoryBean的构造方法中,用来生成对应的bean对象
        MapperScan mapperScan = new MapperScan();
        ArrayList<Class> classes = null;
        try {
           classes = mapperScan.scan(MapperConfig.class);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //进行注册
        for (Class cl:classes) {
            //通过BeanDefinitionBuilder获取beanDefinition这个属性
            AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();

            //指定我们要修改的类的beanDefinition
            beanDefinition.setBeanClass(UserMapperFactoryBean.class);

            //获取类的构造方法设置构造方法
            beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(cl);

            //把BeanDefinition注册上去,创建Bean对象
            registry.registerBeanDefinition(cl.getName(),beanDefinition);
        }

    }
}
总结:

1.使用@Import注解把用来注册BeanDefinition的类传入到ioc容器中;

2.因为BeanDefinition实现了ImportBeanDefinitionRegistrar这个接口,并且重写了registerBeanDefinitions()这个方法,spring会执行这个方法;

3.registerBeanDefinitions();

这个方法中的registry参数,主要是负责注册BeanDefinition,把注册的BeanDefinition变成Bean对象;

4.我们通过BeanDefinitionFactory来得到BeanDefinition这个参数,把我们需要注册的java类传入,然后就可以设置BeanDefinition参数了(BeanDefinition是通过扫描类或者<bean/>生成的)

5.把设置好的BeanDefinition中注册进BeanDefinitionRegister(BeanDefinitionRegister会执行里面的BeanDefinition生成bean对象)

6.在FactoryBean的实现类中getObject()方法会返回设置好的Bean对象,注册进ioc容器中。在getClass()方法中设置返回的class类型;

#这样子就可以根据传入不同的class对象,返回不同的Bean对象;

 

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值