Skip to content

Commit

Permalink
Update to 3.22.0 (#1282)
Browse files Browse the repository at this point in the history
* support ExcludeBeanNameAutoProxyCreator (#1277)

Co-authored-by: 致节 <[email protected]>
(cherry picked from commit f708c0c)

* 1. skip low cost spring.context.config-classes.enhance and bean-factory #1270
2. Support ExcludeBeanNameAutoProxyCreator #1277
3. avoid ReadinessCheckListener cuncrrency

* relase 3.22.0

---------

Co-authored-by: 致节 <[email protected]>
  • Loading branch information
HzjNeverStop and 致节 authored Jan 25, 2024
1 parent 9505851 commit fcd365c
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 4 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
<description>SOFABoot Build</description>

<properties>
<revision>3.21.0</revision>
<revision>3.22.0</revision>
<sofa.boot.version>${revision}</sofa.boot.version>
<!--maven plugin-->
<maven.staging.plugin>1.6.7</maven.staging.plugin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -71,11 +72,11 @@ public class ReadinessCheckListener implements ApplicationContextAware, Ordered,

private boolean healthCheckerStatus = true;

private Map<String, Health> healthCheckerDetails = new HashMap<>();
private Map<String, Health> healthCheckerDetails = new ConcurrentHashMap<>();

private boolean healthIndicatorStatus = true;

private Map<String, Health> healthIndicatorDetails = new HashMap<>();
private Map<String, Health> healthIndicatorDetails = new ConcurrentHashMap<>();

private boolean healthCallbackStatus = true;
private boolean readinessCheckFinish = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,23 @@ public class StartupReporter {

public static final String SPRING_CONTEXT_BEAN_FACTORY_POST_PROCESSOR = "spring.context.bean-factory.post-process";

public static final String SPRING_BEAN_POST_PROCESSOR = "spring.context.beans.post-process";

public static final String SPRING_CONFIG_CLASSES_ENHANCE = "spring.context.config-classes.enhance";

public static final Collection<String> SPRING_BEAN_INSTANTIATE_TYPES = new HashSet<>();

public static final Collection<String> SPRING_CONTEXT_POST_PROCESSOR_TYPES = new HashSet<>();

public static final Collection<String> SPRING_CONFIG_CLASSES_ENHANCE_TYPES = new HashSet<>();

static {
SPRING_BEAN_INSTANTIATE_TYPES.add(SPRING_BEANS_INSTANTIATE);
SPRING_BEAN_INSTANTIATE_TYPES.add(SPRING_BEANS_SMART_INSTANTIATE);
SPRING_CONTEXT_POST_PROCESSOR_TYPES.add(SPRING_CONTEXT_BEANDEF_REGISTRY_POST_PROCESSOR);
SPRING_CONTEXT_POST_PROCESSOR_TYPES.add(SPRING_CONTEXT_BEAN_FACTORY_POST_PROCESSOR);
SPRING_CONFIG_CLASSES_ENHANCE_TYPES.add(SPRING_CONFIG_CLASSES_ENHANCE);
SPRING_CONFIG_CLASSES_ENHANCE_TYPES.add(SPRING_BEAN_POST_PROCESSOR);
}

private final StartupStaticsModel startupStaticsModel = new StartupStaticsModel();
Expand Down Expand Up @@ -175,7 +183,9 @@ public List<BeanStat> generateBeanStats(ConfigurableApplicationContext context)

private boolean filterBeanInitializeByCost(BeanStat beanStat) {
String name = beanStat.getBeanType();
if (SPRING_BEAN_INSTANTIATE_TYPES.contains(name)) {
if (SPRING_BEAN_INSTANTIATE_TYPES.contains(name)
|| SPRING_CONTEXT_POST_PROCESSOR_TYPES.contains(name)
|| SPRING_CONFIG_CLASSES_ENHANCE_TYPES.contains(name)) {
return beanStat.getCost() >= beanInitCostThreshold;
} else {
return true;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* 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.alipay.sofa.boot.aop.framework.autoproxy;

import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.PatternMatchUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
* Extension for {@link BeanNameAutoProxyCreator} to support exclude specify bean names.
*
* @author huzijie
* @version ExcludeBeanNameAutoProxyCreator.java, v 0.1 2024年01月04日 4:24 PM huzijie Exp $
*/
public class ExcludeBeanNameAutoProxyCreator extends BeanNameAutoProxyCreator {

@Nullable
private List<String> excludeBeanNames;

/**
* Set the names of the beans that should not automatically get wrapped with proxies.
* A name can specify a prefix to match by ending with "*", e.g. "myBean,tx*"
* will match the bean named "myBean" and all beans whose name start with "tx".
* <p><b>NOTE:</b> In case of a FactoryBean, only the objects created by the
* FactoryBean will get proxied. This default behavior applies as of Spring 2.0.
* If you intend to proxy a FactoryBean instance itself (a rare use case, but
* Spring 1.2's default behavior), specify the bean name of the FactoryBean
* including the factory-bean prefix "&amp;": e.g. "&amp;myFactoryBean".
* @see org.springframework.beans.factory.FactoryBean
* @see org.springframework.beans.factory.BeanFactory#FACTORY_BEAN_PREFIX
*/
public void setExcludeBeanNames(String... beanNames) {
Assert.notEmpty(beanNames, "'excludeBeanNames' must not be empty");
this.excludeBeanNames = new ArrayList<>(beanNames.length);
for (String mappedName : beanNames) {
this.excludeBeanNames.add(StringUtils.trimWhitespace(mappedName));
}
}

@Override
protected boolean isMatch(String beanName, String mappedName) {
return super.isMatch(beanName, mappedName) && !isExcluded(beanName);
}

private boolean isExcluded(String beanName) {
if (excludeBeanNames != null) {
for (String mappedName : this.excludeBeanNames) {
if (PatternMatchUtils.simpleMatch(mappedName, beanName)) {
return true;
}
}
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* 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.alipay.sofa.boot.aop.framework.autoproxy;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import static org.assertj.core.api.Assertions.assertThat;

/**
* Tests for {@link ExcludeBeanNameAutoProxyCreator}.
*
* @author huzijie
* @version ExcludeBeanNameAutoProxyCreatorTests.java, v 0.1 2024年01月04日 4:36 PM huzijie Exp $
*/
public class ExcludeBeanNameAutoProxyCreatorTest {

@Test
public void excludeBeanNames() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
ExcludeBeanNameAutoProxyCreatorTestConfiguration.class);
SampleInterface sampleA = context.getBean("sampleA", SampleInterface.class);
SampleInterface sampleB = context.getBean("sampleBeanB", SampleInterface.class);
SampleInterface sampleC = context.getBean("sampleBeanC", SampleInterface.class);
assertThat(sampleA.hello()).isEqualTo("hello");
assertThat(sampleB.hello()).isEqualTo("aop");
assertThat(sampleC.hello()).isEqualTo("hello");
}

@Configuration
static class ExcludeBeanNameAutoProxyCreatorTestConfiguration {

@Bean
public SampleInterface sampleA() {
return new SampleInterfaceImpl();
}

@Bean
public SampleInterface sampleBeanB() {
return new SampleInterfaceImpl();
}

@Bean
public SampleInterface sampleBeanC() {
return new SampleInterfaceImpl();
}

@Bean
public ExcludeBeanNameAutoProxyCreator excludeBeanNameAutoProxyCreator() {
ExcludeBeanNameAutoProxyCreator autoProxyCreator = new ExcludeBeanNameAutoProxyCreator();
autoProxyCreator.setBeanNames("sampleBean*");
autoProxyCreator.setExcludeBeanNames("sampleBeanC");
autoProxyCreator.setInterceptorNames("sampleAdvisor");
return autoProxyCreator;
}

@Bean
public MethodInterceptor sampleAdvisor() {
return new MethodInterceptor() {
@Nullable
@Override
public Object invoke(@Nonnull MethodInvocation invocation) {
return "aop";
}
};
}
}

interface SampleInterface {

String hello();
}

static class SampleInterfaceImpl implements SampleInterface {

@Override
public String hello() {
return "hello";
}
}
}

0 comments on commit fcd365c

Please sign in to comment.