简单模拟Spring整合Mybatis

整体包结构

 

 

 

首选我们需要一个接口类,相当于是Mapper


package
com.fh.mybatis.dao; import com.fh.mybatis.config.Select; public interface CardDao { @Select("select * from demo") void list(String mess); }

然后是接口类中用到的注解类

package com.fh.mybatis.config;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Select {

    String value() default "";
}

之后需要一个类,提供代理对象和执行具体的方法

因为实现类FactoryBean接口的类,实例化的时候,会返回getObject方法所返回的对象

package com.fh.mybatis.config;

import org.springframework.beans.factory.FactoryBean;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MyFactoryBean implements FactoryBean, InvocationHandler {

    private Class aClass;

    public MyFactoryBean(Class cla){
        this.aClass = cla;
    }


    @Override
    public Object getObject() {
        Class[] classes = new Class[] {aClass};
        Object object = Proxy.newProxyInstance(this.getClass().getClassLoader(), classes, this);
        return object;
    }

    @Override
    public Class<?> getObjectType() {
        return aClass;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Exception{
        Method list = proxy.getClass().getInterfaces()[0].getMethod(method.getName(), String.class);
        Select select = list.getDeclaredAnnotation(Select.class);
        System.out.println(select.value());
        return null;
    }
}

然后,需要将实例的对象添加到Spring容器中,但是Spring容器中的对象,是通过BeanDefinition创建出来的,所以需要添加一个能够注册BeanDefinitionde 类

package com.fh.mybatis;

import com.fh.mybatis.config.LubanScan;
import com.fh.mybatis.config.MyFactoryBean;
import com.fh.mybatis.dao.CardDao;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.type.AnnotationMetadata;

public class MyImportBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {


    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        MergedAnnotations annotations = importingClassMetadata.getAnnotations();
        MergedAnnotation<LubanScan> lubanScanMergedAnnotation = annotations.get(LubanScan.class);
        String value = lubanScanMergedAnnotation.getString("value");
        System.out.println("----------");
        System.out.println(value);
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CardDao.class);
        GenericBeanDefinition beanDefinition =(GenericBeanDefinition) builder.getBeanDefinition();
        beanDefinition.getConstructorArgumentValues().addGenericArgumentValue("com.fh.mybatis.dao.CardDao");
        beanDefinition.setBeanClass(MyFactoryBean.class);
        registry.registerBeanDefinition("cardDao",beanDefinition);
    }
}

最后添加一个注解,去处理上面这个类

package com.fh.mybatis.config;

import com.fh.mybatis.MyImportBeanDefinitionRegister;
import org.springframework.context.annotation.Import;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(MyImportBeanDefinitionRegister.class)
public @interface LubanScan {

    String value() default "";
}

然后进行一下测试,添加一个配置类

package com.fh.mybatis.config;

import org.springframework.context.annotation.Configuration;

@Configuration
@LubanScan("com.fh")
public class MybatisConfig {
}

最后从容器中获取对象,然后调用接口中的方法,打印sql语句

 

posted @ 2020-03-30 17:59  默默行走  阅读(281)  评论(0编辑  收藏  举报