Spring 不为 ServiceListFactoryBean 对象创建代理
Spring Not Creating Proxy For ServiceListFactoryBean Objects
我正在使用 ServiceFactoryBean 和 ServiceListFactoryBean 收集一些 SPI 实现实例,并自动连接到我的服务 bean。现在我已经创建了一些方面来拦截这些 类 以测量性能和记录调用。
我注意到 spring 正在为 ServiceFactoryBean 捕获并注入服务 bean 的实例创建代理。但它不会为 ServiceListFactoryBean 捕获的实例列表创建任何代理。
我如何告诉 spring 为这些 bean 创建我的方面起作用的代理?
以下是我的代码片段-
收集 SPI 实现并公开它们以进行自动装配的配置
@Bean
public ServiceFactoryBean faceImageStorageProvider() {
ServiceFactoryBean serviceFactoryBean = new ServiceFactoryBean();
serviceFactoryBean.setServiceType(FaceImageStorageProvider.class);
return serviceFactoryBean;
}
@Bean
public ServiceListFactoryBean notificationSenders() {
ServiceListFactoryBean serviceListFactoryBean = new ServiceListFactoryBean();
serviceListFactoryBean.setServiceType(NotificationSender.class);
return serviceListFactoryBean;
}
方面
(这个有效)
@Pointcut("execution(* com.xxx.spi.storage.FaceImageStorageProvider.*(..))")
private void anyFaceImageStorageProviderAPI() {}
(这个不行)
@Pointcut("execution(* com.xxx.spi.notification.NotificationSender.*(..))")
private void anyNotificationSenderAPI() {}
仅供参考,我通过以下方式以编程方式创建代理解决了这个问题 -
@Autowired
private NotificationPerformanceLogger notificationPerformanceLogger;
@Bean
public List<NotificationSender> notificationSenders() {
LOGGER.info("Crating proxy for NotificationSender implementations");
List<NotificationSender> senders = getAvailableNotificationSenders();
LOGGER.debug("Found [{}] NotificationSender implementations", CollectionUtils.size(senders));
return createProxiedNotificationSendersAsSpringWillNotCreateProxyForThese(senders);
}
private List<NotificationSender> getAvailableNotificationSenders() {
List<NotificationSender> senders = new ArrayList<>();
try {
ServiceListFactoryBean serviceListFactoryBean = new ServiceListFactoryBean();
serviceListFactoryBean.setServiceType(NotificationSender.class);
serviceListFactoryBean.afterPropertiesSet();
senders = (List<NotificationSender>) serviceListFactoryBean.getObject();
} catch (Exception ex) {
LOGGER.error("Unable to retrieve notification sender implementations", ex);
}
return senders;
}
private List<NotificationSender> createProxiedNotificationSendersAsSpringWillNotCreateProxyForThese(List<NotificationSender> notificationSenders) {
List<NotificationSender> proxyNotificationSenders = new ArrayList<>();
for (NotificationSender sender : notificationSenders) {
proxyNotificationSenders.add(createAspectJProxy(sender));
}
return proxyNotificationSenders;
}
private NotificationSender createAspectJProxy(NotificationSender notificationSender) {
AspectJProxyFactory aspectJProxyFactory = new AspectJProxyFactory(notificationSender);
aspectJProxyFactory.addAspect(notificationPerformanceLogger);
return aspectJProxyFactory.getProxy();
}
我正在使用 ServiceFactoryBean 和 ServiceListFactoryBean 收集一些 SPI 实现实例,并自动连接到我的服务 bean。现在我已经创建了一些方面来拦截这些 类 以测量性能和记录调用。
我注意到 spring 正在为 ServiceFactoryBean 捕获并注入服务 bean 的实例创建代理。但它不会为 ServiceListFactoryBean 捕获的实例列表创建任何代理。
我如何告诉 spring 为这些 bean 创建我的方面起作用的代理?
以下是我的代码片段-
收集 SPI 实现并公开它们以进行自动装配的配置
@Bean
public ServiceFactoryBean faceImageStorageProvider() {
ServiceFactoryBean serviceFactoryBean = new ServiceFactoryBean();
serviceFactoryBean.setServiceType(FaceImageStorageProvider.class);
return serviceFactoryBean;
}
@Bean
public ServiceListFactoryBean notificationSenders() {
ServiceListFactoryBean serviceListFactoryBean = new ServiceListFactoryBean();
serviceListFactoryBean.setServiceType(NotificationSender.class);
return serviceListFactoryBean;
}
方面 (这个有效)
@Pointcut("execution(* com.xxx.spi.storage.FaceImageStorageProvider.*(..))")
private void anyFaceImageStorageProviderAPI() {}
(这个不行)
@Pointcut("execution(* com.xxx.spi.notification.NotificationSender.*(..))")
private void anyNotificationSenderAPI() {}
仅供参考,我通过以下方式以编程方式创建代理解决了这个问题 -
@Autowired
private NotificationPerformanceLogger notificationPerformanceLogger;
@Bean
public List<NotificationSender> notificationSenders() {
LOGGER.info("Crating proxy for NotificationSender implementations");
List<NotificationSender> senders = getAvailableNotificationSenders();
LOGGER.debug("Found [{}] NotificationSender implementations", CollectionUtils.size(senders));
return createProxiedNotificationSendersAsSpringWillNotCreateProxyForThese(senders);
}
private List<NotificationSender> getAvailableNotificationSenders() {
List<NotificationSender> senders = new ArrayList<>();
try {
ServiceListFactoryBean serviceListFactoryBean = new ServiceListFactoryBean();
serviceListFactoryBean.setServiceType(NotificationSender.class);
serviceListFactoryBean.afterPropertiesSet();
senders = (List<NotificationSender>) serviceListFactoryBean.getObject();
} catch (Exception ex) {
LOGGER.error("Unable to retrieve notification sender implementations", ex);
}
return senders;
}
private List<NotificationSender> createProxiedNotificationSendersAsSpringWillNotCreateProxyForThese(List<NotificationSender> notificationSenders) {
List<NotificationSender> proxyNotificationSenders = new ArrayList<>();
for (NotificationSender sender : notificationSenders) {
proxyNotificationSenders.add(createAspectJProxy(sender));
}
return proxyNotificationSenders;
}
private NotificationSender createAspectJProxy(NotificationSender notificationSender) {
AspectJProxyFactory aspectJProxyFactory = new AspectJProxyFactory(notificationSender);
aspectJProxyFactory.addAspect(notificationPerformanceLogger);
return aspectJProxyFactory.getProxy();
}