Overall package structure
We need a preferred interface class, the equivalent Mapper
package com.fh.mybatis.dao; import com.fh.mybatis.config.Select; public interface CardDao { @Select("select * from demo") void list(String mess); }
Then annotation class interface used in class
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 ""; }
After a required class, the proxy object to provide a method and implementation of specific
Because the interface implementation class FactoryBean class, instantiated, it returns the object returned by the method 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; } }
Then, you need to add an object instance to the Spring container, but the Spring container object is created by BeanDefinition out, so you need to add a class to register 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); } }
Finally add a comment, to deal with on top of the class
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 ""; }
And then test it, add a configuration class
package com.fh.mybatis.config; import org.springframework.context.annotation.Configuration; @Configuration @LubanScan("com.fh") public class MybatisConfig { }
Finally Gets an object from the container, and then call the interface method, print sql statement