How to invoke the method of injecting objects into a class?
cilfm opened this issue · 2 comments
cilfm commented
I want to implement the mybatis framework data query interface,I have create Mapper class and serviceImpl class as follows:
@Mapper
public interface SysCnDistrictMapper extends BaseMapper<BaseEntity> {
@Select(databaseId = "", value = {"select * from sys_cn_district"})
List<Map<String, Object>> apfDycapiDist(@Param("querys") Map<String, Object> paramMap);
}
@Service("")
@Transactional(timeout = -1, label = {}, propagation = Propagation.REQUIRED, noRollbackFor = {}, isolation = Isolation.DEFAULT, rollbackFor = {}, timeoutString = "", transactionManager = "", rollbackForClassName = {}, noRollbackForClassName = {}, value = "", readOnly = false)
public class SysCnDistrictServiceImpl extends ServiceImpl<SysCnDistrictMapper, BaseEntity> implements ISysCnDistrictService {
public List<Map<String, Object>> apfDycapiDist(Map<String, Object> paramMap) {
(SysCnDistrictMapper)getBaseMapper();
return apfDycapiDist(paramMap);
// Expected code not generated
}
}
The code for creating the serviceImpl class is as follows:
private Class<?> createServiceImpl(ApfDynamicApiEntity apiEntity, Class<?> serviceClass, Class<?> mapperClass) {
TableBeanInfo beanInfo = getTableBeanInfo(apiEntity.getPrimaryTable(), BeanType.ServiceImpl);
List<AnnotationDescription> annotations = new ArrayList<>();
annotations.add(AnnotationDescription.Builder.ofType(Service.class).build());
annotations.add(AnnotationDescription.Builder.ofType(Transactional.class).build());
Class<?> serviceImplClass = new ByteBuddy()
.subclass(TypeDescription.Generic.Builder.parameterizedType(ServiceImpl.class, mapperClass, BaseEntity.class).build())
.implement(serviceClass)
.name(beanInfo.getClassName())
.annotateType(annotations)
.method(ElementMatchers.named(getMethodName(apiEntity.getApiPath())))
.intercept(
MethodCall.invoke(ElementMatchers.named("getBaseMapper"))
.andThen(MethodCall.invoke(ElementMatchers.named(getMethodName(apiEntity.getApiPath()))).withAllArguments())
)
.make();
.load(getClass().getClassLoader(), ClassLoadingStrategy.Default.INJECTION)
.getLoaded();
try {
SpringUtil.registerBean(beanInfo.getBeanName(), serviceImplClass.newInstance());
} catch (InstantiationException | IllegalAccessException e) {
log.error("fail to register {}", beanInfo.toString(), e);
}
return serviceImplClass;
}
How to generate the following code?
@Service
@Transactional(timeout = -1, label = {}, propagation = Propagation.REQUIRED, noRollbackFor = {}, isolation = Isolation.DEFAULT, rollbackFor = {}, timeoutString = "", transactionManager = "", rollbackForClassName = {}, noRollbackForClassName = {}, value = "", readOnly = false)
public class SysCnDistrictServiceImpl extends ServiceImpl<SysCnDistrictMapper, BaseEntity> implements ISysCnDistrictService {
public List<Map<String, Object>> apfDycapiDist(Map<String, Object> paramMap) {
return baseMapper.apfDycapiDist(paramMap);
// or
// return (SysCnDistrictMapper)getBaseMapper().apfDycapiDist(paramMap);
}
}
raphw commented
Possibly you are looking for MethodDelegation
? You would be able to supply any arguments and return any value, Byte Buddy then weaves it into the method.
cilfm commented
Thank you! I have resolved it.
MethodDelegation.toField("baseMapper")