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

issues-28645 #28652

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package org.springframework.beans.factory.config;

/**
* Bean life cycle Notice
*
* @author Zen Huifer
*/
public interface BeanLifecycleNotice {


void notice(BeanLifecycleEnum lifecycleEnum, BeanLifecycleEvent event);

/**
* Bean life cycle type
*/
enum BeanLifecycleEnum {
created,
destroyed,
}

/**
* Bean life cycle event
*/
class BeanLifecycleEvent {
/**
* event name
*/
private String beanName;


/**
* bean instance
*/
private Object bean;



public BeanLifecycleEvent(String beanName, Object bean) {
this.beanName = beanName;
this.bean = bean;
}

public String getBeanName() {
return beanName;
}

public void setBeanName(String beanName) {
this.beanName = beanName;
}

public Object getBean() {
return bean;
}

public void setBean(Object bean) {
this.bean = bean;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,15 @@ default Object postProcessAfterInitialization(Object bean, String beanName) thro
return bean;
}

/**
* Used to determine whether the current beanPostProcess can process
* @param bean the new bean instance
* @param beanName the name of the bean
* @return true or false
*/
@Nullable
default boolean support(Object bean, String beanName) {
return true;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
* @param beanPostProcessor the post-processor to register
*/
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
void addBeanLifecycleNotice(BeanLifecycleNotice beanLifecycleNotice);

/**
* Return the current number of registered BeanPostProcessors, if any.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.AutowiredPropertyMarker;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanLifecycleNotice;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
Expand Down Expand Up @@ -124,22 +125,6 @@
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {

/** Strategy for creating bean instances. */
private InstantiationStrategy instantiationStrategy;

/** Resolver strategy for method parameter names. */
@Nullable
private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();

/** Whether to automatically try to resolve circular references between beans. */
private boolean allowCircularReferences = true;

/**
* Whether to resort to injecting a raw bean instance in case of circular reference,
* even if the injected bean eventually got wrapped.
*/
private boolean allowRawInjectionDespiteWrapping = false;

/**
* Dependency types to ignore on dependency check and autowire, as Set of
* Class objects: for example, String. Default is none.
Expand Down Expand Up @@ -168,6 +153,22 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
private final ConcurrentMap<Class<?>, PropertyDescriptor[]> filteredPropertyDescriptorsCache =
new ConcurrentHashMap<>();

/** Strategy for creating bean instances. */
private InstantiationStrategy instantiationStrategy;

/** Resolver strategy for method parameter names. */
@Nullable
private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();

/** Whether to automatically try to resolve circular references between beans. */
private boolean allowCircularReferences = true;

/**
* Whether to resort to injecting a raw bean instance in case of circular reference,
* even if the injected bean eventually got wrapped.
*/
private boolean allowRawInjectionDespiteWrapping = false;


/**
* Create a new AbstractAutowireCapableBeanFactory.
Expand All @@ -194,6 +195,12 @@ public AbstractAutowireCapableBeanFactory(@Nullable BeanFactory parentBeanFactor
setParentBeanFactory(parentBeanFactory);
}

/**
* Return the instantiation strategy to use for creating bean instances.
*/
protected InstantiationStrategy getInstantiationStrategy() {
return this.instantiationStrategy;
}

/**
* Set the instantiation strategy to use for creating bean instances.
Expand All @@ -205,10 +212,12 @@ public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy
}

/**
* Return the instantiation strategy to use for creating bean instances.
* Return the ParameterNameDiscoverer to use for resolving method parameter
* names if needed.
*/
protected InstantiationStrategy getInstantiationStrategy() {
return this.instantiationStrategy;
@Nullable
protected ParameterNameDiscoverer getParameterNameDiscoverer() {
return this.parameterNameDiscoverer;
}

/**
Expand All @@ -221,12 +230,12 @@ public void setParameterNameDiscoverer(@Nullable ParameterNameDiscoverer paramet
}

/**
* Return the ParameterNameDiscoverer to use for resolving method parameter
* names if needed.
* Return whether to allow circular references between beans.
* @since 5.3.10
* @see #setAllowCircularReferences
*/
@Nullable
protected ParameterNameDiscoverer getParameterNameDiscoverer() {
return this.parameterNameDiscoverer;
public boolean isAllowCircularReferences() {
return this.allowCircularReferences;
}

/**
Expand All @@ -247,12 +256,12 @@ public void setAllowCircularReferences(boolean allowCircularReferences) {
}

/**
* Return whether to allow circular references between beans.
* Return whether to allow the raw injection of a bean instance.
* @since 5.3.10
* @see #setAllowCircularReferences
* @see #setAllowRawInjectionDespiteWrapping
*/
public boolean isAllowCircularReferences() {
return this.allowCircularReferences;
public boolean isAllowRawInjectionDespiteWrapping() {
return this.allowRawInjectionDespiteWrapping;
}

/**
Expand All @@ -273,15 +282,6 @@ public void setAllowRawInjectionDespiteWrapping(boolean allowRawInjectionDespite
this.allowRawInjectionDespiteWrapping = allowRawInjectionDespiteWrapping;
}

/**
* Return whether to allow the raw injection of a bean instance.
* @since 5.3.10
* @see #setAllowRawInjectionDespiteWrapping
*/
public boolean isAllowRawInjectionDespiteWrapping() {
return this.allowRawInjectionDespiteWrapping;
}

/**
* Ignore the given dependency type for autowiring:
* for example, String. Default is none.
Expand Down Expand Up @@ -437,11 +437,13 @@ public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, S

Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
if (processor.support(result, beanName)) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
result = current;
}
return result;
}
Expand All @@ -452,19 +454,25 @@ public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, St

Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
if (processor.support(result, beanName)) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
result = current;

}
for (BeanLifecycleNotice beanLifecycleNotice : getBeanLifecycleNotices()) {
beanLifecycleNotice.notice(BeanLifecycleNotice.BeanLifecycleEnum.created,new BeanLifecycleNotice.BeanLifecycleEvent(beanName,existingBean));
}
return result;
}

@Override
public void destroyBean(Object existingBean) {
new DisposableBeanAdapter(
existingBean, getBeanPostProcessorCache().destructionAware, getAccessControlContext()).destroy();
existingBean, getBeanPostProcessorCache().destructionAware, getAccessControlContext(),getBeanLifecycleNotices()).destroy();
}


Expand Down Expand Up @@ -646,11 +654,11 @@ else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
Expand Down Expand Up @@ -1811,6 +1819,11 @@ protected Object initializeBean(String beanName, Object bean, @Nullable RootBean
return wrappedBean;
}

/**
* todo: 生命周期通知
* @param beanName
* @param bean
*/
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.BeanExpressionContext;
import org.springframework.beans.factory.config.BeanExpressionResolver;
import org.springframework.beans.factory.config.BeanLifecycleNotice;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
Expand Down Expand Up @@ -159,6 +160,11 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
/** BeanPostProcessors to apply. */
private final List<BeanPostProcessor> beanPostProcessors = new BeanPostProcessorCacheAwareList();

/**
* BeanLifecycleNotice to apply.
*/
private final List<BeanLifecycleNotice> beanLifecycleNotices = new CopyOnWriteArrayList<>();

/** Cache of pre-filtered post-processors. */
@Nullable
private volatile BeanPostProcessorCache beanPostProcessorCache;
Expand Down Expand Up @@ -950,6 +956,13 @@ public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
this.beanPostProcessors.add(beanPostProcessor);
}

@Override
public void addBeanLifecycleNotice(BeanLifecycleNotice beanLifecycleNotice) {
Assert.notNull(beanLifecycleNotice, "BeanLifecycleNotice must not be null");
this.beanLifecycleNotices.remove(beanLifecycleNotice);
this.beanLifecycleNotices.add(beanLifecycleNotice);
}

/**
* Add new BeanPostProcessors that will get applied to beans created
* by this factory. To be invoked during factory configuration.
Expand All @@ -974,6 +987,10 @@ public List<BeanPostProcessor> getBeanPostProcessors() {
return this.beanPostProcessors;
}

public List<BeanLifecycleNotice> getBeanLifecycleNotices() {
return beanLifecycleNotices;
}

/**
* Return the internal cache of pre-filtered post-processors,
* freshly (re-)building it if necessary.
Expand Down Expand Up @@ -1222,7 +1239,7 @@ public void destroyBean(String beanName, Object beanInstance) {
*/
protected void destroyBean(String beanName, Object bean, RootBeanDefinition mbd) {
new DisposableBeanAdapter(
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, getAccessControlContext()).destroy();
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, getAccessControlContext(),getBeanLifecycleNotices()).destroy();
}

@Override
Expand Down Expand Up @@ -1932,7 +1949,7 @@ protected void registerDisposableBeanIfNecessary(String beanName, Object bean, R
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
registerDisposableBean(beanName, new DisposableBeanAdapter(
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc,getBeanLifecycleNotices()));
}
else {
// A bean with a custom scope...
Expand All @@ -1941,7 +1958,7 @@ protected void registerDisposableBeanIfNecessary(String beanName, Object bean, R
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc,getBeanLifecycleNotices()));
}
}
}
Expand Down
Loading