如何强制 BeanPostProcessor 代理查找 类 而不是接口?
How force BeanPostProcessor proxy to look up on classes not interfaces?
我不确定问题是否正确,因为我在这方面还是新手。
我想使用 BeanPostProcessor
完成以下场景:
- 过滤所有标有
@Service
注解的bean。
- 过滤所有自身具有标记注释
@Refreshable
的方法。
- 对这些方法的 return 个对象执行指定的方法。
下面是我的工作示例:
@Retention(RUNTIME)
public @interface Refreshable {
}
public interface VisitServiceI {
@Refreshable
VisitDtoOut addVisitToPatient(UUID idPatient, VisitDtoIn visitDtoIn);
}
public interface RefreshableDto {
void copyId();
}
@Component
public class MethodBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof VisitServiceI) {
ProxyFactory factory = new ProxyFactory(bean);
factory.addInterface(VisitServiceI.class);
factory.addAdvice((AfterReturningAdvice) (returnValue, method, args, target) -> {
if (method.isAnnotationPresent(Refreshable.class)) {
var refreshableDto = (RefreshableDto) returnValue;
if (refreshableDto != null) {
refreshableDto.copyId();
}
}
});
factory.setExposeProxy(true);
return factory.getProxy();
}
return bean;
}
}
是否可以摆脱那些无用的接口,例如:VisitServiceI
当我给他标准 类 而不是它们的接口时,我想强迫 BeanPostProcessor
以某种方式工作。
放弃 BeanPostProcessor
,只写一个方面,让 Spring 来做繁重的工作。
@Aspect
@Component
public RefreshableAspect {
@AfterReturn("within(@Service) && @annotation(@Refreshable)", returning="retVal")
public void refresh(Object retVal) {
if (retVal instanceof RefreshableDto) {
((RefreshableDto) retVal).copyId();
}
}
}
类似的东西将在没有接口和额外的情况下完成你需要的东西 BeanPostProcessor
。
但如果您真的想要复杂的路线,请执行以下操作
@Component
public class MethodBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (AnnotationUtils.findAnnotation(bean.getClass(), Service.class) != null) {
ProxyFactory factory = new ProxyFactory(bean);
factory.setProxyTargetClass(true);
factory.addAdvice((AfterReturningAdvice) (returnValue, method, args, target) -> {
if (method.isAnnotationPresent(Refreshable.class)) {
var refreshableDto = (RefreshableDto) returnValue;
if (refreshableDto != null) {
refreshableDto.copyId();
}
}
});
factory.setExposeProxy(true);
return factory.getProxy();
}
return bean;
}
}
我不确定问题是否正确,因为我在这方面还是新手。
我想使用 BeanPostProcessor
完成以下场景:
- 过滤所有标有
@Service
注解的bean。 - 过滤所有自身具有标记注释
@Refreshable
的方法。 - 对这些方法的 return 个对象执行指定的方法。
下面是我的工作示例:
@Retention(RUNTIME)
public @interface Refreshable {
}
public interface VisitServiceI {
@Refreshable
VisitDtoOut addVisitToPatient(UUID idPatient, VisitDtoIn visitDtoIn);
}
public interface RefreshableDto {
void copyId();
}
@Component
public class MethodBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof VisitServiceI) {
ProxyFactory factory = new ProxyFactory(bean);
factory.addInterface(VisitServiceI.class);
factory.addAdvice((AfterReturningAdvice) (returnValue, method, args, target) -> {
if (method.isAnnotationPresent(Refreshable.class)) {
var refreshableDto = (RefreshableDto) returnValue;
if (refreshableDto != null) {
refreshableDto.copyId();
}
}
});
factory.setExposeProxy(true);
return factory.getProxy();
}
return bean;
}
}
是否可以摆脱那些无用的接口,例如:VisitServiceI
当我给他标准 类 而不是它们的接口时,我想强迫 BeanPostProcessor
以某种方式工作。
放弃 BeanPostProcessor
,只写一个方面,让 Spring 来做繁重的工作。
@Aspect
@Component
public RefreshableAspect {
@AfterReturn("within(@Service) && @annotation(@Refreshable)", returning="retVal")
public void refresh(Object retVal) {
if (retVal instanceof RefreshableDto) {
((RefreshableDto) retVal).copyId();
}
}
}
类似的东西将在没有接口和额外的情况下完成你需要的东西 BeanPostProcessor
。
但如果您真的想要复杂的路线,请执行以下操作
@Component
public class MethodBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (AnnotationUtils.findAnnotation(bean.getClass(), Service.class) != null) {
ProxyFactory factory = new ProxyFactory(bean);
factory.setProxyTargetClass(true);
factory.addAdvice((AfterReturningAdvice) (returnValue, method, args, target) -> {
if (method.isAnnotationPresent(Refreshable.class)) {
var refreshableDto = (RefreshableDto) returnValue;
if (refreshableDto != null) {
refreshableDto.copyId();
}
}
});
factory.setExposeProxy(true);
return factory.getProxy();
}
return bean;
}
}