Enhancer. create ()
При необходимости создайте новый класс и используйте указанные обратные вызовы (если есть) для создания нового экземпляра объекта. Использует конструктор без аргументов суперкласса.
создает новый экземпляр настроенного SuperClass
. Новый экземпляр не является компонентом, управляемым пружиной, и, следовательно, внедрение зависимостей не произошло. Также обратите внимание, что поведение transactional
метода startTracking()
также будет потеряно с экземпляром Enhancer.
Чтобы обойти NPE, вам нужно будет установить компонент репозитория программным способом.
Я сделал следующее изменение кода, чтобы заставить код работать
@Service
public class RequestTrackingService implements CompensateAware {
public RequestTrackingRepository repository;
public RequestTrackingService(RequestTrackingRepository repository) {
this.repository = repository;
}
@Transactional
public void startTracking() {
RequestTrackingEntity requestTrackingEntity = new RequestTrackingEntity();
requestTrackingEntity.setStatus(TransactionStatus.RECEIVED);
requestTrackingEntity.setId(ServiceContext.getTrackingNo());
repository.proxyRepoTestMethod();
}
public RequestTrackingRepository getRepository() {
return repository;
}
}
и
//Create proxy using cglib
private Object beanProxy(Object bean) {
Enhancer enhancer = new Enhancer();
// Set RequestTrackingService as the super class
enhancer.setSuperclass(((Advised)bean).getTargetClass());
enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
System.out.println("SOME LOG BEFORE METHOD");
return methodProxy.invokeSuper(o, objects);
});
RequestTrackingService serviceBean = (RequestTrackingService)enhancer.create(new Class[] {RequestTrackingRepository.class}, new Object[] {((RequestTrackingService)bean).getRepository()});
return serviceBean;
}
Надеюсь, это поможет
Обновление 1: Это может быть не полный ответ. Я не могу напечатать строку "SOME LOG BEFORE METHOD"
с этим изменением кода.
Обновление 2: Оказывается, что bean.getClass()
возвращает класс уже улучшенного объекта (прокси, созданного пружиной). Это каким-то образом предотвращает регистрацию кода в коде делегирования proxyMethod.
пример класса перезапущен:
class com.xxx.xxx.proxy.RequestTrackingService$$EnhancerBySpringCGLIB$$40bcb718
Изменение кода для установки фактического целевого класса устраняет проблему ведения журнала а также.
enhancer.setSuperclass(((Advised)bean).getTargetClass());
Последний вопрос, хотя бы, какая-либо конкретная c причина, по которой вы не используете Spring AOP для этого варианта использования?