Skip to content

Commit

Permalink
Merge pull request #319 from dromara/optimize
Browse files Browse the repository at this point in the history
[ISSUE #318] fix npe when use dtp execute runnable in @bean method
  • Loading branch information
yanhom1314 committed Aug 2, 2023
2 parents e04430c + bfad4ea commit e3e4cf2
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 141 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* 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 org.dromara.dynamictp.common.spring;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;

import java.util.List;
import java.util.Map;

/**
* SpringBeanHelper related
*
* @author yanhom
* @since 1.0.4
**/
@Slf4j
public final class SpringBeanHelper {

private SpringBeanHelper() { }

public static void register(BeanDefinitionRegistry registry,
String beanName,
Class<?> clazz,
Map<String, Object> propertyValues,
Object... constructorArgs) {
register(registry, beanName, clazz, propertyValues, null, constructorArgs);
}

public static void register(BeanDefinitionRegistry registry,
String beanName,
Class<?> clazz,
Map<String, Object> propertyValues,
List<String> dependsOnBeanNames,
Object... constructorArgs) {
if (ifPresent(registry, beanName, clazz) || registry.containsBeanDefinition(beanName)) {
log.info("DynamicTp registrar, bean [{}] already exists and will be overwritten", beanName);
registry.removeBeanDefinition(beanName);
}
doRegister(registry, beanName, clazz, propertyValues, dependsOnBeanNames, constructorArgs);
}

public static void registerIfAbsent(BeanDefinitionRegistry registry,
String beanName,
Class<?> clazz,
Object... constructorArgs) {
registerIfAbsent(registry, beanName, clazz, null, null, constructorArgs);
}

public static void registerIfAbsent(BeanDefinitionRegistry registry,
String beanName,
Class<?> clazz,
Map<String, Object> propertyValues,
Object... constructorArgs) {
registerIfAbsent(registry, beanName, clazz, propertyValues, null, constructorArgs);
}

public static void registerIfAbsent(BeanDefinitionRegistry registry,
String beanName,
Class<?> clazz,
Map<String, Object> propertyValues,
List<String> dependsOnBeanNames,
Object... constructorArgs) {
if (!ifPresent(registry, beanName, clazz) && !registry.containsBeanDefinition(beanName)) {
doRegister(registry, beanName, clazz, propertyValues, dependsOnBeanNames, constructorArgs);
}
}

public static boolean ifPresent(BeanDefinitionRegistry registry, String beanName, Class<?> clazz) {
String[] beanNames = getBeanNames((ListableBeanFactory) registry, clazz);
return ArrayUtils.contains(beanNames, beanName);
}

public static String[] getBeanNames(ListableBeanFactory beanFactory, Class<?> clazz) {
return beanFactory.getBeanNamesForType(clazz, true, false);
}

private static void doRegister(BeanDefinitionRegistry registry,
String beanName,
Class<?> clazz,
Map<String, Object> propertyValues,
List<String> dependsOnBeanNames,
Object... constructorArgs) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
for (Object constructorArg : constructorArgs) {
builder.addConstructorArgValue(constructorArg);
}
if (MapUtils.isNotEmpty(propertyValues)) {
propertyValues.forEach(builder::addPropertyValue);
}
if (CollectionUtils.isNotEmpty(dependsOnBeanNames)) {
dependsOnBeanNames.forEach(builder::addDependsOn);
}
registry.registerBeanDefinition(beanName, builder.getBeanDefinition());
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,14 @@
package org.dromara.dynamictp.core.spring;

import org.dromara.dynamictp.common.properties.DtpProperties;
import org.dromara.dynamictp.common.timer.HashedWheelTimer;
import org.dromara.dynamictp.core.DtpRegistry;
import org.dromara.dynamictp.core.monitor.DtpMonitor;
import org.dromara.dynamictp.core.support.DtpBannerPrinter;
import org.dromara.dynamictp.core.thread.NamedThreadFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;

import java.util.concurrent.TimeUnit;

/**
* DtpBaseBeanConfiguration related
*
Expand Down Expand Up @@ -64,10 +60,4 @@ public DtpMonitor dtpMonitor(DtpProperties dtpProperties) {
public DtpBannerPrinter dtpBannerPrinter() {
return new DtpBannerPrinter();
}

@Bean
public HashedWheelTimer hashedWheelTimer() {
return new HashedWheelTimer(new NamedThreadFactory("dtpRunnable-timeout", true), 10, TimeUnit.MILLISECONDS);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* 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 org.dromara.dynamictp.core.spring;

import com.google.common.collect.Lists;
import org.dromara.dynamictp.common.spring.ApplicationContextHolder;
import org.dromara.dynamictp.common.spring.SpringBeanHelper;
import org.dromara.dynamictp.common.timer.HashedWheelTimer;
import org.dromara.dynamictp.core.thread.NamedThreadFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

import java.util.concurrent.TimeUnit;

/**
* DtpBaseProcessorRegistrar related
*
* @author yanhom
* @since 1.0.4
**/
public class DtpBaseProcessorRegistrar implements ImportBeanDefinitionRegistrar {

private static final String APPLICATION_CONTEXT_HOLDER = "dtpApplicationContextHolder";

private static final String HASHED_WHEEL_TIMER = "dtpHashedWheelTimer";

private static final String DTP_POST_PROCESSOR = "dtpPostProcessor";

@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
registerHashedWheelTimer(registry);
SpringBeanHelper.registerIfAbsent(registry, APPLICATION_CONTEXT_HOLDER, ApplicationContextHolder.class);

// ApplicationContextHolder and HashedWheelTimer are required in DtpExecutor execute method, so they must be registered first
SpringBeanHelper.registerIfAbsent(registry, DTP_POST_PROCESSOR, DtpPostProcessor.class,
null, Lists.newArrayList(APPLICATION_CONTEXT_HOLDER, HASHED_WHEEL_TIMER));
}

private void registerHashedWheelTimer( BeanDefinitionRegistry registry) {
Object[] constructorArgs = new Object[] {
new NamedThreadFactory("dtp-runnable-timeout", true),
10,
TimeUnit.MILLISECONDS
};
SpringBeanHelper.registerIfAbsent(registry, HASHED_WHEEL_TIMER, HashedWheelTimer.class, constructorArgs);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import org.apache.commons.collections4.CollectionUtils;
import org.dromara.dynamictp.common.entity.DtpExecutorProps;
import org.dromara.dynamictp.common.properties.DtpProperties;
import org.dromara.dynamictp.common.util.BeanUtil;
import org.dromara.dynamictp.common.spring.SpringBeanHelper;
import org.dromara.dynamictp.core.reject.RejectHandlerGetter;
import org.dromara.dynamictp.core.support.BinderHelper;
import org.dromara.dynamictp.core.support.ExecutorType;
Expand Down Expand Up @@ -88,7 +88,7 @@ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, B
Class<?> executorTypeClass = ExecutorType.getClass(e.getExecutorType());
Map<String, Object> propertyValues = buildPropertyValues(e);
Object[] args = buildConstructorArgs(executorTypeClass, e);
BeanUtil.registerIfAbsent(registry, e.getThreadPoolName(), executorTypeClass, propertyValues, args);
SpringBeanHelper.register(registry, e.getThreadPoolName(), executorTypeClass, propertyValues, args);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

package org.dromara.dynamictp.core.spring;

import org.dromara.dynamictp.common.spring.ApplicationContextHolder;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.DeferredImportSelector;
Expand Down Expand Up @@ -47,10 +46,9 @@ public String[] selectImports(AnnotationMetadata metadata) {
if (!BooleanUtils.toBoolean(environment.getProperty(DTP_ENABLED_PROP, BooleanUtils.TRUE))) {
return new String[]{};
}
return new String[]{
return new String[] {
DtpBaseProcessorRegistrar.class.getName(),
DtpBeanDefinitionRegistrar.class.getName(),
DtpPostProcessorRegistrar.class.getName(),
ApplicationContextHolder.class.getName(),
DtpBaseBeanConfiguration.class.getName()
};
}
Expand Down

This file was deleted.

0 comments on commit e3e4cf2

Please sign in to comment.