Skip to content

Commit

Permalink
Support singleton PostProcessor (#1029)
Browse files Browse the repository at this point in the history
  • Loading branch information
HzjNeverStop authored Oct 26, 2022
1 parent 98a7345 commit 186ba07
Show file tree
Hide file tree
Showing 17 changed files with 340 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
*/
package com.alipay.sofa.boot.autoconfigure.runtime;

import com.alipay.sofa.runtime.proxy.ProxyBeanFactoryPostProcessor;
import com.alipay.sofa.runtime.SofaFramework;
import com.alipay.sofa.runtime.api.client.ReferenceClient;
import com.alipay.sofa.runtime.api.client.ServiceClient;
import com.alipay.sofa.runtime.client.impl.ClientFactoryImpl;
import com.alipay.sofa.runtime.component.impl.StandardSofaRuntimeManager;
import com.alipay.sofa.runtime.configure.SofaRuntimeConfigurationProperties;
import com.alipay.sofa.runtime.proxy.ProxyBeanFactoryPostProcessor;
import com.alipay.sofa.runtime.service.client.ReferenceClientImpl;
import com.alipay.sofa.runtime.service.client.ServiceClientImpl;
import com.alipay.sofa.runtime.service.impl.BindingAdapterFactoryImpl;
Expand All @@ -46,10 +46,8 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.core.env.Environment;

import java.util.HashSet;
Expand Down Expand Up @@ -128,11 +126,8 @@ public static SofaRuntimeContext sofaRuntimeContext(SofaRuntimeManager sofaRunti

@Bean
@ConditionalOnMissingBean
public static RuntimeContextBeanFactoryPostProcessor runtimeContextBeanFactoryPostProcessor(BindingAdapterFactory bindingAdapterFactory,
BindingConverterFactory bindingConverterFactory,
SofaRuntimeContext sofaRuntimeContext) {
return new RuntimeContextBeanFactoryPostProcessor(bindingAdapterFactory,
bindingConverterFactory, sofaRuntimeContext);
public static RuntimeContextBeanFactoryPostProcessor runtimeContextBeanFactoryPostProcessor() {
return new RuntimeContextBeanFactoryPostProcessor();
}

@Bean
Expand All @@ -145,23 +140,22 @@ public static JvmFilterPostProcessor jvmFilterPostProcessor() {
@ConditionalOnMissingBean
@ConditionalOnClass(name = "com.alipay.sofa.isle.ApplicationRuntimeModel")
@ConditionalOnProperty(value = "com.alipay.sofa.boot.enable-isle", matchIfMissing = true)
public static SofaShareBeanFactoryPostProcessor sofaModuleBeanFactoryPostProcessor(SofaPostProcessorShareManager shareManager) {
return new SofaShareBeanFactoryPostProcessor(shareManager);
public static SofaShareBeanFactoryPostProcessor sofaModuleBeanFactoryPostProcessor() {
return new SofaShareBeanFactoryPostProcessor();
}

@Bean
@ConditionalOnMissingBean
@ConditionalOnClass(name = "com.alipay.sofa.isle.ApplicationRuntimeModel")
@ConditionalOnProperty(value = "com.alipay.sofa.boot.enable-isle", matchIfMissing = true)
public SofaPostProcessorShareManager sofaModulePostProcessorShareManager(ApplicationContext applicationContext) {
return new SofaPostProcessorShareManager((AbstractApplicationContext) applicationContext);
public SofaPostProcessorShareManager sofaModulePostProcessorShareManager() {
return new SofaPostProcessorShareManager();
}

@Bean
@ConditionalOnMissingBean
public static ServiceBeanFactoryPostProcessor serviceBeanFactoryPostProcessor(SofaRuntimeContext sofaRuntimeContext,
BindingConverterFactory bindingConverterFactory) {
return new ServiceBeanFactoryPostProcessor(sofaRuntimeContext, bindingConverterFactory);
public static ServiceBeanFactoryPostProcessor serviceBeanFactoryPostProcessor() {
return new ServiceBeanFactoryPostProcessor();
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.alipay.sofa.runtime.context.SofaApplicationContext;
import com.alipay.sofa.runtime.factory.BeanLoadCostBeanFactory;
import com.alipay.sofa.runtime.log.SofaLogger;
import com.alipay.sofa.runtime.spring.singleton.SingletonSofaPostProcessor;
import com.alipay.sofa.runtime.util.SofaSpringContextUtil;
import org.springframework.beans.CachedIntrospectionResults;
import org.springframework.beans.factory.config.BeanDefinition;
Expand All @@ -33,6 +34,7 @@
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.Resource;
import org.springframework.util.StringUtils;

Expand Down Expand Up @@ -150,7 +152,16 @@ protected void addPostProcessors(DefaultListableBeanFactory beanFactory) {
.getBean(SofaBootConstants.PROCESSORS_OF_ROOT_APPLICATION_CONTEXT);
for (Map.Entry<String, BeanDefinition> entry : processors.entrySet()) {
if (!beanFactory.containsBeanDefinition(entry.getKey())) {
beanFactory.registerBeanDefinition(entry.getKey(), entry.getValue());
Class<?> type = rootApplicationContext.getType(entry.getKey());
if (type != null
&& AnnotationUtils.findAnnotation(type, SingletonSofaPostProcessor.class) != null) {
// 复用单例
beanFactory.registerSingleton(entry.getKey(),
rootApplicationContext.getBean(entry.getKey()));
} else {
// 注册 BeanDefinition
beanFactory.registerBeanDefinition(entry.getKey(), entry.getValue());
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ public void test() {
@EnableConfigurationProperties(SofaModuleProperties.class)
public static class FailModuleTestConfiguration {
@Bean
public static SofaShareBeanFactoryPostProcessor sofaModuleBeanFactoryPostProcessor(SofaPostProcessorShareManager shareManager) {
return new SofaShareBeanFactoryPostProcessor(shareManager);
public static SofaShareBeanFactoryPostProcessor sofaModuleBeanFactoryPostProcessor() {
return new SofaShareBeanFactoryPostProcessor();
}

@Bean
Expand Down Expand Up @@ -133,9 +133,8 @@ public SofaModuleProfileChecker sofaModuleProfileChecker(SofaModuleProperties so

@Bean
@ConditionalOnMissingBean
public SofaPostProcessorShareManager sofaModulePostProcessorShareManager(ApplicationContext applicationContext) {
return new SofaPostProcessorShareManager(
(AbstractApplicationContext) applicationContext);
public SofaPostProcessorShareManager sofaModulePostProcessorShareManager() {
return new SofaPostProcessorShareManager();
}

@Bean(destroyMethod = "")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -72,15 +72,14 @@ static class ProcessorConfig {

@Bean
@ConditionalOnMissingBean
public SofaPostProcessorShareManager sofaModulePostProcessorShareManager(ApplicationContext applicationContext) {
return new SofaPostProcessorShareManager(
(AbstractApplicationContext) applicationContext);
public SofaPostProcessorShareManager sofaModulePostProcessorShareManager() {
return new SofaPostProcessorShareManager();
}

@Bean
@ConditionalOnMissingBean
public static SofaShareBeanFactoryPostProcessor sofaModuleBeanFactoryPostProcessor(SofaPostProcessorShareManager shareManager) {
return new SofaShareBeanFactoryPostProcessor(shareManager);
public static SofaShareBeanFactoryPostProcessor sofaModuleBeanFactoryPostProcessor() {
return new SofaShareBeanFactoryPostProcessor();
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*
* 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.isle.test;

import com.alipay.sofa.isle.profile.DefaultSofaModuleProfileChecker;
import com.alipay.sofa.isle.profile.SofaModuleProfileChecker;
import com.alipay.sofa.isle.spring.SofaModuleContextLifecycle;
import com.alipay.sofa.isle.spring.config.SofaModuleProperties;
import com.alipay.sofa.isle.stage.DefaultPipelineContext;
import com.alipay.sofa.isle.stage.ModelCreatingStage;
import com.alipay.sofa.isle.stage.ModuleLogOutputStage;
import com.alipay.sofa.isle.stage.PipelineContext;
import com.alipay.sofa.isle.stage.PipelineStage;
import com.alipay.sofa.isle.stage.SpringContextInstallStage;
import com.alipay.sofa.isle.test.processor.SampleBeanPostProcessor;
import com.alipay.sofa.isle.test.processor.SingletonBeanPostProcessor;
import com.alipay.sofa.isle.test.util.AddCustomJar;
import com.alipay.sofa.isle.test.util.SeparateClassLoaderTestRunner;
import com.alipay.sofa.runtime.SofaFramework;
import com.alipay.sofa.runtime.client.impl.ClientFactoryImpl;
import com.alipay.sofa.runtime.component.impl.StandardSofaRuntimeManager;
import com.alipay.sofa.runtime.spi.client.ClientFactoryInternal;
import com.alipay.sofa.runtime.spi.component.ComponentInfo;
import com.alipay.sofa.runtime.spi.component.SofaRuntimeManager;
import com.alipay.sofa.runtime.spring.SofaShareBeanFactoryPostProcessor;
import com.alipay.sofa.runtime.spring.SpringContextComponent;
import com.alipay.sofa.runtime.spring.share.SofaPostProcessorShareManager;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.AbstractApplicationContext;

import java.util.Collection;
import java.util.List;

/**
* @author huzijie
* @version SingletonProcessorTest.java, v 0.1 2022年10月25日 11:33 AM huzijie Exp $
*/
@RunWith(SeparateClassLoaderTestRunner.class)
@SpringBootTest
@AddCustomJar({ "dev-module-0.1.0.jar" })
public class SingletonProcessorTest {

@Autowired
private SingletonBeanPostProcessor singletonBeanPostProcessor;

@Autowired
private SampleBeanPostProcessor sampleBeanPostProcessor;

@Autowired
private SofaRuntimeManager sofaRuntimeManager;

@Test
public void testSingletonBpp() {
Collection<ComponentInfo> components =
sofaRuntimeManager.getComponentManager().getComponentInfosByType(SpringContextComponent.SPRING_COMPONENT_TYPE);
ApplicationContext applicationContext = components.stream().filter(componentInfo -> componentInfo.getName().getRawName().contains("dev")).findFirst().get().getApplicationContext();
SingletonBeanPostProcessor singletonBeanPostProcessor = applicationContext.getBean(SingletonBeanPostProcessor.class);
SampleBeanPostProcessor sampleBeanPostProcessor = applicationContext.getBean(SampleBeanPostProcessor.class);
Assert.assertEquals(singletonBeanPostProcessor, this.singletonBeanPostProcessor);
Assert.assertNotEquals(sampleBeanPostProcessor, this.sampleBeanPostProcessor);
}

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(SofaModuleProperties.class)
public static class SofaModuleProfileCheckerTestConfiguration {

@Bean
public static SofaShareBeanFactoryPostProcessor sofaModuleBeanFactoryPostProcessor() {
return new SofaShareBeanFactoryPostProcessor();
}

@Bean
@ConditionalOnMissingBean
public SofaModuleContextLifecycle sofaModuleContextLifecycle(PipelineContext pipelineContext) {
return new SofaModuleContextLifecycle(pipelineContext);
}

@Bean
@ConditionalOnMissingBean
public ModelCreatingStage modelCreatingStage(ApplicationContext applicationContext,
SofaModuleProperties sofaModuleProperties,
SofaModuleProfileChecker sofaModuleProfileChecker) {
return new ModelCreatingStage((AbstractApplicationContext) applicationContext,
sofaModuleProperties, sofaModuleProfileChecker);
}

@Bean
@ConditionalOnMissingBean
public SpringContextInstallStage springContextInstallStage(ApplicationContext applicationContext,
SofaModuleProperties sofaModuleProperties) {
return new SpringContextInstallStage((AbstractApplicationContext) applicationContext,
sofaModuleProperties);
}

@Bean
@ConditionalOnMissingBean
public ModuleLogOutputStage moduleLogOutputStage(ApplicationContext applicationContext) {
return new ModuleLogOutputStage((AbstractApplicationContext) applicationContext);
}

@Bean
@ConditionalOnMissingBean
public PipelineContext pipelineContext(List<PipelineStage> stageList) {
return new DefaultPipelineContext(stageList);
}

@Bean
@ConditionalOnMissingBean
public SofaModuleProfileChecker sofaModuleProfileChecker(SofaModuleProperties sofaModuleProperties) {
return new DefaultSofaModuleProfileChecker(sofaModuleProperties);
}

@Bean
@ConditionalOnMissingBean
public SofaPostProcessorShareManager sofaModulePostProcessorShareManager() {
return new SofaPostProcessorShareManager();
}

@Bean(destroyMethod = "")
@ConditionalOnMissingBean
public static SofaRuntimeManager sofaRuntimeManager() {
ClientFactoryInternal clientFactoryInternal = new ClientFactoryImpl();
SofaRuntimeManager sofaRuntimeManager = new StandardSofaRuntimeManager(
"FailModuleTest", Thread.currentThread().getContextClassLoader(),
clientFactoryInternal);
SofaFramework.registerSofaRuntimeManager(sofaRuntimeManager);
return sofaRuntimeManager;
}

@Bean
public SingletonBeanPostProcessor singletonBeanPostProcessor() {
return new SingletonBeanPostProcessor();
}

@Bean
public SampleBeanPostProcessor sampleBeanPostProcessor() {
return new SampleBeanPostProcessor();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* 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.isle.test.processor;

import com.alipay.sofa.runtime.spring.singleton.SingletonSofaPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
* @author huzijie
* @version SingletonBeanPostProcessor.java, v 0.1 2022年10月25日 11:33 AM huzijie Exp $
*/
@SingletonSofaPostProcessor
public class SingletonBeanPostProcessor implements BeanPostProcessor {
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,17 +94,13 @@ public static SofaRuntimeContext sofaRuntimeContext(SofaRuntimeManager sofaRunti
}

@Bean
public static RuntimeContextBeanFactoryPostProcessor runtimeContextBeanFactoryPostProcessor(BindingAdapterFactory bindingAdapterFactory,
BindingConverterFactory bindingConverterFactory,
SofaRuntimeContext sofaRuntimeContext) {
return new RuntimeContextBeanFactoryPostProcessor(bindingAdapterFactory,
bindingConverterFactory, sofaRuntimeContext);
public static RuntimeContextBeanFactoryPostProcessor runtimeContextBeanFactoryPostProcessor() {
return new RuntimeContextBeanFactoryPostProcessor();
}

@Bean
public static ServiceBeanFactoryPostProcessor serviceBeanFactoryPostProcessor(SofaRuntimeContext sofaRuntimeContext,
BindingConverterFactory bindingConverterFactory) {
return new ServiceBeanFactoryPostProcessor(sofaRuntimeContext, bindingConverterFactory);
public static ServiceBeanFactoryPostProcessor serviceBeanFactoryPostProcessor() {
return new ServiceBeanFactoryPostProcessor();
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package com.alipay.sofa.runtime.proxy;

import com.alipay.sofa.runtime.spring.singleton.SingletonSofaPostProcessor;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils;
Expand All @@ -32,6 +33,7 @@
* @author ruoshan
* @since 3.12.0
*/
@SingletonSofaPostProcessor
public class ProxyBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor,
PriorityOrdered {

Expand Down
Loading

0 comments on commit 186ba07

Please sign in to comment.