Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spring Framework / Spring Boot Enhancements #1611

Merged
merged 12 commits into from
Apr 23, 2018
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory;
import com.alibaba.dubbo.config.support.Parameter;

import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import com.alibaba.dubbo.config.ServiceConfig;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory;

import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.BeanNameAware;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* 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 org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.PropertyValues;
import org.springframework.core.env.PropertyResolver;

import java.lang.annotation.Annotation;

import static com.alibaba.dubbo.config.spring.util.AnnotationUtils.getAttributes;

/**
* {@link Annotation} {@link PropertyValues} Adapter
*
* @see Annotation
* @see PropertyValues
* @since 2.5.11
*/
class AnnotationPropertyValuesAdapter implements PropertyValues {

private final Annotation annotation;

private final PropertyResolver propertyResolver;

private final boolean ignoreDefaultValue;

private final PropertyValues delegate;

public AnnotationPropertyValuesAdapter(Annotation annotation, PropertyResolver propertyResolver, boolean ignoreDefaultValue, String... ignoreAttributeNames) {
this.annotation = annotation;
this.propertyResolver = propertyResolver;
this.ignoreDefaultValue = ignoreDefaultValue;
this.delegate = adapt(annotation, ignoreDefaultValue, ignoreAttributeNames);
}

public AnnotationPropertyValuesAdapter(Annotation annotation, PropertyResolver propertyResolver, String... ignoreAttributeNames) {
this(annotation, propertyResolver, true, ignoreAttributeNames);
}

private PropertyValues adapt(Annotation annotation, boolean ignoreDefaultValue, String... ignoreAttributeNames) {
return new MutablePropertyValues(getAttributes(annotation, propertyResolver, ignoreDefaultValue, ignoreAttributeNames));
}

public Annotation getAnnotation() {
return annotation;
}

public boolean isIgnoreDefaultValue() {
return ignoreDefaultValue;
}

@Override
public PropertyValue[] getPropertyValues() {
return delegate.getPropertyValues();
}

@Override
public PropertyValue getPropertyValue(String propertyName) {
return delegate.getPropertyValue(propertyName);
}

@Override
public PropertyValues changesSince(PropertyValues old) {
return delegate.changesSince(old);
}

@Override
public boolean contains(String propertyName) {
return delegate.contains(propertyName);
}

@Override
public boolean isEmpty() {
return delegate.isEmpty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,19 @@
package com.alibaba.dubbo.config.spring.beans.factory.annotation;

import com.alibaba.dubbo.common.utils.Assert;
import com.alibaba.dubbo.config.AbstractConfig;
import com.alibaba.dubbo.config.spring.context.annotation.DubboConfigBindingRegistrar;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubboConfigBinding;
import com.alibaba.dubbo.config.spring.context.properties.DefaultDubboConfigBinder;
import com.alibaba.dubbo.config.spring.context.properties.DubboConfigBinder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.validation.DataBinder;

import java.util.Arrays;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.env.Environment;

/**
* Dubbo Config Binding {@link BeanPostProcessor}
Expand All @@ -35,54 +38,123 @@
* @see DubboConfigBindingRegistrar
* @since 2.5.8
*/
public class DubboConfigBindingBeanPostProcessor implements BeanPostProcessor {

public class DubboConfigBindingBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware, InitializingBean {

private final Log log = LogFactory.getLog(getClass());

/**
* Binding Bean Name
* The prefix of Configuration Properties
*/
private final String beanName;
private final String prefix;

/**
* Binding {@link PropertyValues}
* Binding Bean Name
*/
private final PropertyValues propertyValues;
private final String beanName;

private DubboConfigBinder dubboConfigBinder;

private ApplicationContext applicationContext;

private boolean ignoreUnknownFields = true;

private boolean ignoreInvalidFields = true;

/**
* @param beanName Binding Bean Name
* @param propertyValues {@link PropertyValues}
* @param prefix the prefix of Configuration Properties
* @param beanName the binding Bean Name
*/
public DubboConfigBindingBeanPostProcessor(String beanName, PropertyValues propertyValues) {
public DubboConfigBindingBeanPostProcessor(String prefix, String beanName) {
Assert.notNull(prefix, "The prefix of Configuration Properties must not be null");
Assert.notNull(beanName, "The name of bean must not be null");
Assert.notNull(propertyValues, "The PropertyValues of bean must not be null");
this.prefix = prefix;
this.beanName = beanName;
this.propertyValues = propertyValues;
}

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

if (beanName.equals(this.beanName)) {
DataBinder dataBinder = new DataBinder(bean);
// TODO ignore invalid fields by annotation attribute
dataBinder.setIgnoreInvalidFields(true);
dataBinder.bind(propertyValues);
if (beanName.equals(this.beanName) && bean instanceof AbstractConfig) {

AbstractConfig dubboConfig = (AbstractConfig) bean;

dubboConfigBinder.bind(prefix, dubboConfig);

if (log.isInfoEnabled()) {
log.info("The properties of bean [name : " + beanName + "] have been binding by values : "
+ Arrays.asList(propertyValues.getPropertyValues()));
log.info("The properties of bean [name : " + beanName + "] have been binding by prefix of " +
"configuration properties : " + prefix);
}
}

return bean;

}

public boolean isIgnoreUnknownFields() {
return ignoreUnknownFields;
}

public void setIgnoreUnknownFields(boolean ignoreUnknownFields) {
this.ignoreUnknownFields = ignoreUnknownFields;
}

public boolean isIgnoreInvalidFields() {
return ignoreInvalidFields;
}

public void setIgnoreInvalidFields(boolean ignoreInvalidFields) {
this.ignoreInvalidFields = ignoreInvalidFields;
}

public DubboConfigBinder getDubboConfigBinder() {
return dubboConfigBinder;
}

public void setDubboConfigBinder(DubboConfigBinder dubboConfigBinder) {
this.dubboConfigBinder = dubboConfigBinder;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}

@Override
public void afterPropertiesSet() throws Exception {

if (dubboConfigBinder == null) {
try {
dubboConfigBinder = applicationContext.getBean(DubboConfigBinder.class);
} catch (BeansException ignored) {
if (log.isDebugEnabled()) {
log.debug("DubboConfigBinder Bean can't be found in ApplicationContext.");
}
// Use Default implementation
dubboConfigBinder = createDubboConfigBinder(applicationContext.getEnvironment());
}
}

dubboConfigBinder.setIgnoreUnknownFields(ignoreUnknownFields);
dubboConfigBinder.setIgnoreInvalidFields(ignoreInvalidFields);

}

/**
* Create {@link DubboConfigBinder} instance.
*
* @param environment
* @return {@link DefaultDubboConfigBinder}
*/
protected DubboConfigBinder createDubboConfigBinder(Environment environment) {
DefaultDubboConfigBinder defaultDubboConfigBinder = new DefaultDubboConfigBinder();
defaultDubboConfigBinder.setEnvironment(environment);
return defaultDubboConfigBinder;
}

}
Loading