整体包结构
首选我们需要一个接口类,相当于是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语句