模拟MapperFactoryBean实现对接口的代理,相关代码如下:
@Data
public class PersonInfo {
private int id;
private String name;
private int age;
}
public interface PersonMapper {
@Results(id = "personMap", value = {@Result(property = "id", column = "id"),
@Result(property = "name", column = "name"), @Result(property = "age", column = "age")})
@Select("select * from person where name=#{name}; ")
public PersonInfo selectByName(String personName);
@Select("select * from person;")
@ResultMap(value = "personMap")
public List<PersonInfo> selectAll();
}
@Retention(RetentionPolicy.RUNTIME)
@Import(MyBeanDefinitionRegistrar.class)
public @interface MyBatisMonitor {}
@Configuration
@ComponentScan(value = "xyz.xxx.demo.config")
@MyBatisMonitor
public class DemoConfig {}
public class MyBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition();
AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(PersonMapper.class);
beanDefinition.setBeanClass(MyMapperFactoryBean.class);
registry.registerBeanDefinition("personMapper", beanDefinition);
}
}
public class MyMapperFactoryBean implements FactoryBean, InvocationHandler {
public Class clazz;
public MyMapperFactoryBean(Class clazz) {
this.clazz = clazz;
}
@Nullable
@Override
public Object getObject() throws Exception {
return Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] {clazz}, this);
}
@Nullable
@Override
public Class<?> getObjectType() {
return clazz;
}
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
System.out.println(clazz.getName() + ">>>>>>>>>>>>>>>>>>>>>>>>>>>> proxy invoke!");
method.invoke(clazz,objects);
return null;
}
}
public class MybatisDemoApplication {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext annotationConfigApplicationContext =
new AnnotationConfigApplicationContext(DemoConfig.class);
PersonMapper personMapper = (PersonMapper)annotationConfigApplicationContext.getBean("personMapper");
System.out.println(">>>>>>>>>"+personMapper.getClass());
}
}