Preface: I want to proxy some classes and intercept their methods (using cglib
and BeanPostProcessor
). These classes are spring beans (@Service
) and normally they have some dependency like a repository
.
Problem: When I create a proxy for a bean, the dependencies of the proxy class are null
(they are not injected into proxy class).
what should I do to the dependency of proxy class injected properly?
Scenario: I want to create a proxy for service
classes that implemented a CompensateAware
interface and then I want to print some log before invoking their methods.
My codes are as follows
Service class (Original Class)
@Service
public class RequestTrackingService implements CompensateAware {
@Autowired
public RequestTrackingRepository repository;
@Transactional
public void startTracking() {
RequestTrackingEntity requestTrackingEntity = new RequestTrackingEntity();
requestTrackingEntity.setStatus(TransactionStatus.RECEIVED);
requestTrackingEntity.setId(ServiceContext.getTrackingNo());
repository.save(requestTrackingEntity);
}
}
Create Proxt Classes using BeanPostProcessor
and cglib
@Component
public class ServiceProxy implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof CompensateAware) {
return beanProxy(bean);
} else return bean;
}
//Create proxy using cglib
private Object beanProxy(Object bean) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(bean.getClass());
enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
System.out.println("SOME LOG BEFORE METHOD");
return methodProxy.invokeSuper(o, objects);
});
return enhancer.create();
}
}
Call service
method (startTracking
)
@Service
public class TestClass {
@Autowired
private RequestTrackingService service;
public void test() {
//I get NullPointerException because of null dependency (repository) in service
service.startTracking();
}
}
In short:
When i call startTracking
method (method of proxy class) somewhere in my app, i get NullPointerException
, because its dependency(repository
) is not injected and it's null`.