blob: 5d9418fbc8a676ce33a7a862285ed5474a1407d3 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.dubbo.config.spring.beans.factory.annotation;
import com.alibaba.dubbo.config.ConsumerConfig;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.spring.ReferenceBean;
import com.alibaba.dubbo.config.spring.convert.converter.StringArrayToMapConverter;
import com.alibaba.dubbo.config.spring.convert.converter.StringArrayToStringConverter;
import org.springframework.context.ApplicationContext;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.DataBinder;
import static com.alibaba.dubbo.config.spring.util.BeanFactoryUtils.getOptionalBean;
import static com.alibaba.dubbo.config.spring.util.ObjectUtils.of;
/**
* {@link ReferenceBean} Builder
*
* @since 2.5.7
*/
class ReferenceBeanBuilder extends AbstractAnnotationConfigBeanBuilder<Reference, ReferenceBean> {
private ReferenceBeanBuilder(Reference annotation, ClassLoader classLoader, ApplicationContext applicationContext) {
super(annotation, classLoader, applicationContext);
}
private void configureInterface(Reference reference, ReferenceBean referenceBean) {
Class<?> interfaceClass = reference.interfaceClass();
if (void.class.equals(interfaceClass)) {
interfaceClass = null;
String interfaceClassName = reference.interfaceName();
if (StringUtils.hasText(interfaceClassName)) {
if (ClassUtils.isPresent(interfaceClassName, classLoader)) {
interfaceClass = ClassUtils.resolveClassName(interfaceClassName, classLoader);
}
}
}
if (interfaceClass == null) {
interfaceClass = this.interfaceClass;
}
Assert.isTrue(interfaceClass.isInterface(),
"The class of field or method that was annotated @Reference is not an interface!");
referenceBean.setInterface(interfaceClass);
}
private void configureConsumerConfig(Reference reference, ReferenceBean<?> referenceBean) {
String consumerBeanName = reference.consumer();
ConsumerConfig consumerConfig = getOptionalBean(applicationContext, consumerBeanName, ConsumerConfig.class);
referenceBean.setConsumer(consumerConfig);
}
@Override
protected ReferenceBean doBuild() {
return new ReferenceBean<Object>();
}
@Override
protected void preConfigureBean(Reference reference, ReferenceBean referenceBean) {
Assert.notNull(interfaceClass, "The interface class must set first!");
DataBinder dataBinder = new DataBinder(referenceBean);
// Set ConversionService
dataBinder.setConversionService(getConversionService());
// Ignore those fields
String[] ignoreAttributeNames = of("application", "module", "consumer", "monitor", "registry");
// dataBinder.setDisallowedFields(ignoreAttributeNames);
// Bind annotation attributes
dataBinder.bind(new AnnotationPropertyValuesAdapter(reference, applicationContext.getEnvironment(), ignoreAttributeNames));
}
private ConversionService getConversionService() {
DefaultConversionService conversionService = new DefaultConversionService();
conversionService.addConverter(new StringArrayToStringConverter());
conversionService.addConverter(new StringArrayToMapConverter());
return conversionService;
}
@Override
protected String resolveModuleConfigBeanName(Reference annotation) {
return annotation.module();
}
@Override
protected String resolveApplicationConfigBeanName(Reference annotation) {
return annotation.application();
}
@Override
protected String[] resolveRegistryConfigBeanNames(Reference annotation) {
return annotation.registry();
}
@Override
protected String resolveMonitorConfigBeanName(Reference annotation) {
return annotation.monitor();
}
@Override
protected void postConfigureBean(Reference annotation, ReferenceBean bean) throws Exception {
bean.setApplicationContext(applicationContext);
configureInterface(annotation, bean);
configureConsumerConfig(annotation, bean);
bean.afterPropertiesSet();
}
public static ReferenceBeanBuilder create(Reference annotation, ClassLoader classLoader,
ApplicationContext applicationContext) {
return new ReferenceBeanBuilder(annotation, classLoader, applicationContext);
}
}