spring小结(4)--invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

承接上一小节,

介绍invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

//回调实现BeanFactoryPostProcessor的实现类,目前默认加载的processor有ConfigurationClassPostProcessor,

public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
      PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {

。。。。。。。。。

其中;

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

。。。。。。。。。。。。。

那么查看

ConfigurationClassPostProcessor关于BeanFactoryPostProcessor 的实现
/**
 * Prepare the Configuration classes for servicing bean requests at runtime
 * by replacing them with CGLIB-enhanced subclasses.
 */
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   int factoryId = System.identityHashCode(beanFactory);
   if (this.factoriesPostProcessed.contains(factoryId)) {
      throw new IllegalStateException(
            "postProcessBeanFactory already called on this post-processor against " + beanFactory);
   }
   this.factoriesPostProcessed.add(factoryId);
   if (!this.registriesPostProcessed.contains(factoryId)) {
      // BeanDefinitionRegistryPostProcessor hook apparently not supported...
      // Simply call processConfigurationClasses lazily at this point then.
      processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
   }

   enhanceConfigurationClasses(beanFactory);
   beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}

其中调用了cglib为产生Config类产生代理,如果配置类没有加@Configration,下面会直接return, 加了会继续执行

/**
 * Post-processes a BeanFactory in search of Configuration class BeanDefinitions;
 * any candidates are then enhanced by a {@link ConfigurationClassEnhancer}.
 * Candidate status is determined by BeanDefinition attribute metadata.
 * @see ConfigurationClassEnhancer
 */
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
   Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
   for (String beanName : beanFactory.getBeanDefinitionNames()) {
      BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
      if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) { //之前说过有@Configuration,是Full标志,只加@ComponentScan而无@Configuration,是Lite标志,现在那些标志在这里用到了
         if (!(beanDef instanceof AbstractBeanDefinition)) {
            throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" +
                  beanName + "' since it is not stored in an AbstractBeanDefinition subclass");
         }
         else if (logger.isWarnEnabled() && beanFactory.containsSingleton(beanName)) {
            logger.warn("Cannot enhance @Configuration bean definition '" + beanName +
                  "' since its singleton instance has been created too early. The typical cause " +
                  "is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " +
                  "return type: Consider declaring such methods as 'static'.");
         }
         configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
      }
   }
   if (configBeanDefs.isEmpty()) {
      // nothing to enhance -> return immediately
      return;
   }

   ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
   for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
      AbstractBeanDefinition beanDef = entry.getValue();
      // If a @Configuration class gets proxied, always proxy the target class
      beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
      try {
         // Set enhanced subclass of the user-specified bean class
         Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader);
         if (configClass != null) {
            Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
            if (configClass != enhancedClass) {
               if (logger.isDebugEnabled()) {
                  logger.debug(String.format("Replacing bean definition '%s' existing class '%s' with " +
                        "enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
               }
               beanDef.setBeanClass(enhancedClass);
            }

测试下:

加了@config

@Configuration
@ComponentScan("com.lmq.BaseService")
//@Import(MyImportBeanDefinitionRegistrar.class)
@Import(MyImportSelector.class)
public class AppConfig {


}

输出如下:此时appconfig是个cglib增强的代理类

没加,先注释掉
//@Configuration
@ComponentScan("com.lmq.BaseService")
//@Import(MyImportBeanDefinitionRegistrar.class)
@Import(MyImportSelector.class)
public class AppConfig {


}

输出  //此时appconfig是个普通类

 

为了说明cglib代理作用,这里

举个例子

package com.lmq.BaseService;

public class lmqDao {


    public lmqDao()
    {
        System.out.println("lmqdao1-init");
    }
}

无注解

同理public class lmqDao1 {

...........

 

然后在Config类,假设不加@configuration

//@Configuration
@ComponentScan("com.lmq.BaseService")
//@Import(MyImportBeanDefinitionRegistrar.class)
@Import(MyImportSelector.class)
public class AppConfig {


    @Bean
   public  lmqDao indexdao()
    {
        return new lmqDao();
    }

    @Bean
    public lmqDao1 indexdao1()
    {
        indexdao();
        return new lmqDao1();  //没加@Configuration注解,会输出2遍“lmqdao1-init",因为是根据执行方法来产生bean,方法调用了一次,总共2次
    }


}

容器启动输出:

当取消@Configuration注释,加上此注解,只输出一遍

 

就是cglib改变了方法的执行,使用了代理,

之前讲过@configuration是full 注解,会进入后续cglib处理,为config类产生一个cglib代理类,//因为先有class,再有bd,再有bean实例

 */
public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {
   if (EnhancedConfiguration.class.isAssignableFrom(configClass)) {
      if (logger.isDebugEnabled()) {
         logger.debug(String.format("Ignoring request to enhance %s as it has " +
               "already been enhanced. This usually indicates that more than one " +
               "ConfigurationClassPostProcessor has been registered (e.g. via " +
               "<context:annotation-config>). This is harmless, but you may " +
               "want check your configuration and remove one CCPP if possible",
               configClass.getName()));
      }
      return configClass;
   }
   Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));
   if (logger.isDebugEnabled()) {
      logger.debug(String.format("Successfully enhanced %s; enhanced class name is: %s",
            configClass.getName(), enhancedClass.getName()));
   }
   return enhancedClass;
}

接着进入;

private Enhancer newEnhancer(Class<?> superclass, @Nullable ClassLoader classLoader) {
   Enhancer enhancer = new Enhancer();
   enhancer.setSuperclass(superclass);
   enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
   enhancer.setUseFactory(false);
   enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
   enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
   enhancer.setCallbackFilter(CALLBACK_FILTER);
   enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
   return enhancer;
}

对于增强的接口EnhancedConfiguration.class,细看

public interface EnhancedConfiguration extends BeanFactoryAware { //继承了BeanFactoryAware,目的在于让cglib代理的类得到beanfactory
},
而
public interface BeanFactoryAware extends Aware {  //实现此接口的类,经过beanPostProcessor回调此类的setBeanFactory(),可以设置得到BeanFactory ,
    void setBeanFactory(BeanFactory var1) throws BeansException;
}

这里考虑由代理类的代理对象拦截从beanfactory获取bean实例(getBean), 这就不用new 2次了,正如上面cong类加了@Config注解,便有cglib为此配置类生成代理类,代理类实现setbeanfatory或得beanfactory,在调用此配置类的方法拦截,以上面为例,从beanfactory获取bean实例(getBean), 这就不用new 2次了

最下面的方法有个类似:

private Object resolveBeanReference(Method beanMethod, Object[] beanMethodArgs,
ConfigurableBeanFactory beanFactory, String beanName) {

// The user (i.e. not the factory) is requesting this bean through a call to
// the bean method, direct or indirect. The bean may have already been marked
// as 'in creation' in certain autowiring scenarios; if so, temporarily set
// the in-creation status to false in order to avoid an exception.
boolean alreadyInCreation = beanFactory.isCurrentlyInCreation(beanName);
try {
if (alreadyInCreation) {
beanFactory.setCurrentlyInCreation(beanName, false);
}
boolean useArgs = !ObjectUtils.isEmpty(beanMethodArgs);
if (useArgs && beanFactory.isSingleton(beanName)) {
// Stubbed null arguments just for reference purposes,
// expecting them to be autowired for regular singleton references?
// A safe assumption since @Bean singleton arguments cannot be optional...
for (Object arg : beanMethodArgs) {
if (arg == null) {
useArgs = false;
break;
}
}
}
Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) :
beanFactory.getBean(beanName));

if (!ClassUtils.isAssignableValue(beanMethod.getReturnType(), beanInstance)) {
if (beanInstance.equals(null)) {
if (logger.isDebugEnabled()) {
logger.debug(String.format("@Bean method %s.%s called as bean reference " +
"for type [%s] returned null bean; resolving to null value.",
beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName(),
beanMethod.getReturnType().getName()));
}
beanInstance = null;
}
else {
String msg = String.format("@Bean method %s.%s called as bean reference " +
"for type [%s] but overridden by non-compatible bean instance of type [%s].",
beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName(),
beanMethod.getReturnType().getName(), beanInstance.getClass().getName());
try {
BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition(beanName);
msg += " Overriding bean

这里自己可以使用cglib实现代理类自定义拦截:

比如

Enhancer enhancer =new Enhancer();
//增强父类,
enhancer.setSuperclass(lmqDao.class);

enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);

//对目标的代理对象的所有方法拦截
enhancer.setCallback(new TestMethodCallBack());

lmqDao lmqdao= (lmqDao) enhancer.create();

lmqdao.print();

输出:

其中public class lmqDao {


    public lmqDao()
    {
        System.out.println("lmqdao1-init");
    }

    public void print()
    {
        System.out.println("lmqdao - print ------");
    }
}

其中

public class TestMethodCallBack  implements MethodInterceptor {


    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

        System.out.println("method ----");
        return methodProxy.invokeSuper(o,objects);


    }
}

类似jdk代理(需要接口),cglib需要类

回到spring的ConfigurationClassPostProcessor,继续上面的分析,

public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
   Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
   for (String beanName : beanFactory.getBeanDefinitionNames()) {
      BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
      if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {
         if (!(beanDef instanceof AbstractBeanDefinition)) {
            throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" +
                  beanName + "' since it is not stored in an AbstractBeanDefinition subclass");
         }
         else if (logger.isWarnEnabled() && beanFactory.containsSingleton(beanName)) {
            logger.warn("Cannot enhance @Configuration bean definition '" + beanName +
                  "' since its singleton instance has been created too early. The typical cause " +
                  "is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " +
                  "return type: Consider declaring such methods as 'static'.");
         }
         configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
      }
   }
   if (configBeanDefs.isEmpty()) {
      // nothing to enhance -> return immediately
      return;
   }

   ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
   for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
      AbstractBeanDefinition beanDef = entry.getValue();
      // If a @Configuration class gets proxied, always proxy the target class
      beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
      try {
         // Set enhanced sub

。。。。。。。。。。。。。

接着进入

private Enhancer newEnhancer(Class<?> superclass, @Nullable ClassLoader classLoader) {
   Enhancer enhancer = new Enhancer();
   enhancer.setSuperclass(superclass);
   enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
   enhancer.setUseFactory(false);
   enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
   enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
   enhancer.setCallbackFilter(CALLBACK_FILTER); //这里是方法拦截的filter
   enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
   return enhancer;
}

enhancer.setCallbackFilter(CALLBACK_FILTER); //这里是spring实现方法拦截的filter

细看

private static final ConditionalCallbackFilter CALLBACK_FILTER = new ConditionalCallbackFilter(CALLBACKS)

private static final Callback[] CALLBACKS = new Callback[] { new BeanMethodInterceptor(), new BeanFactoryAwareMethodInterceptor(), NoOp.INSTANCE }; //有这几种拦截

 

首先看下BeanMethodInterceptor;

private static class BeanMethodInterceptor implements MethodInterceptor, ConditionalCallback {

   /**
    * Enhance a {@link Bean @Bean} method to check the supplied BeanFactory for the
    * existence of this bean object.
    * @throws Throwable as a catch-all for any exception that may be thrown when invoking the
    * super implementation of the proxied method i.e., the actual {@code @Bean} method
    */
   @Override
   @Nullable
   public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
            MethodProxy cglibMethodProxy) throws Throwable {
            //通过enhancedConfigInstance(代理对象)中cglib生成的成员变量$$beanfactory获得beanFactory
      ConfigurableBeanFactory beanFactory = getBeanFactory(enhancedConfigInstance);
      String beanName = BeanAnnotationHelper.determineBeanNameFor(beanMethod);

      // Determine whether this bean is a scoped-proxy
      Scope scope = AnnotatedElementUtils.findMergedAnnotation(beanMethod, Scope.class);
      if (scope != null && scope.proxyMode() != ScopedProxyMode.NO) {
         String scopedBeanName = ScopedProxyCreator.getTargetBeanName(beanName);
         if (beanFactory.isCurrentlyInCreation(scopedBeanName)) {
            beanName = scopedBeanName;
         }
      }

      // To handle the case of an inter-bean method reference, we must explicitly check the
      // container for already cached instances.

      // First, check to see if the requested bean is a FactoryBean. If so, create a subclass
      // proxy that intercepts calls to getObject() and returns any cached bean instance.
      // This ensures that the semantics of calling a FactoryBean from within @Bean methods
      // is the same as that of referring to a FactoryBean within XML. See SPR-6602.
               //其中BeanFactory.FACTORY_BEAN_PREFIX是“&”,如果能拿到,就是·个factorybean
      if (factoryContainsBean(beanFactory, BeanFactory.FACTORY_BEAN_PREFIX + beanName) &&
            factoryContainsBean(beanFactory, beanName)) {
         Object factoryBean = beanFactory.getBean(BeanFactory.FACTORY_BEAN_PREFIX + beanName);
         if (factoryBean instanceof ScopedProxyFactoryBean) {
            // Scoped proxy factory beans are a special case and should not be further proxied
         }
         else {
            // It is a candidate FactoryBean - go ahead with enhancement
            //假设lmqDao是个factorybean,那么再次进行代理
            return enhanceFactoryBean(factoryBean, beanMethod.getReturnType(), beanFactory, beanName);
           此方法


     
         }
      }

      if (isCurrentlyInvokedFactoryMethod(beanMethod)) {
         // The factory is calling the bean method in order to instantiate and register the bean
         // (i.e. via a getBean() call) -> invoke the super implementation of the method to actually
         // create the bean instance.
         if (logger.isWarnEnabled() &&
               BeanFactoryPostProcessor.class.isAssignableFrom(beanMethod.getReturnType())) {
            logger.warn(String.format("@Bean method %s.%s is non-static and returns an object " +
                        "assignable to Spring's BeanFactoryPostProcessor interface. This will " +
                        "result in a failure to process annotations such as @Autowired, " +
                        "@Resource and @PostConstruct within the method's declaring " +
                        "@Configuration class. Add the 'static' modifier to this method to avoid " +
                        "these container lifecycle issues; see @Bean javadoc for complete details.",
                  beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName()));
         }
         return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
      }

      return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
   }
private Object resolveBeanReference(Method beanMethod, Object[] beanMethodArgs,
      ConfigurableBeanFactory beanFactory, String beanName) {

   // The user (i.e. not the factory) is requesting this bean through a call to
   // the bean method, direct or indirect. The bean may have already been marked
   // as 'in creation' in certain autowiring scenarios; if so, temporarily set
   // the in-creation status to false in order to avoid an exception.
   boolean alreadyInCreation = beanFactory.isCurrentlyInCreation(beanName);
   try {
      if (alreadyInCreation) {
         beanFactory.setCurrentlyInCreation(beanName, false);
      }
      boolean useArgs = !ObjectUtils.isEmpty(beanMethodArgs);
      if (useArgs && beanFactory.isSingleton(beanName)) {
         // Stubbed null arguments just for reference purposes,
         // expecting them to be autowired for regular singleton references?
         // A safe assumption since @Bean singleton arguments cannot be optional...
         for (Object arg : beanMethodArgs) {
            if (arg == null) {
               useArgs = false;
               break;
            }
         }
      }
      Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) :
            beanFactory.getBean(beanName));
      if (!ClassUtils.isAssignableValue(beanMethod.getReturnType(), beanInstance)) {
         if (beanInstance.equals(null)) {
            if (logger.isDebugEnabled()) {
               logger.debug(String.format("@Bean method %s.%s called as bean reference " +
                     "for type [%s] returned null bean; resolving to null value.",
                     beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName(),
                     beanMethod.getReturnType().getName()));
            }
            beanInstance = null;
         }
         else {
            String msg = String.format("@Bean method %s.%s called as bean reference " +
                  "for type [%s] but overridden by non-compatible bean instance of type [%s].",
                  beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName(),
                  beanMethod.getReturnType().getName(), beanInstance.getClass().getName());
            try {
               BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition(beanName);
               msg += " Overriding bean of same name declared in: " + beanDefinition.getResourceDescription();
            }
            catch (NoSuchBeanDefinitionException ex) {
               // Ignore - simply no detailed message then.
            }
            throw new IllegalStateException(msg);
         }
      }
      Method currentlyInvoked = SimpleInstantiationStrategy.getCurrentlyInvokedFactoryMethod();
      if (currentlyInvoked != null) {
         String outerBeanName = BeanAnnotationHelper.determineBeanNameFor(currentlyInvoked);
         beanFactory.registerDependentBean(beanName, outerBeanName);
      }
      return beanInstance;
   }
   finally {
      if (alreadyInCreation) {
         beanFactory.setCurrentlyInCreation(beanName, true);
      }
   }
}

再次看上面截图的最后一个方法(再次代理)//这里第二个代理的是factorybean的getboject方法,第一次代理是cglib为方法拦截代理

private Object createCglibProxyForFactoryBean(final Object factoryBean,
      final ConfigurableBeanFactory beanFactory, final String beanName) {

   Enhancer enhancer = new Enhancer();
   enhancer.setSuperclass(factoryBean.getClass());
   enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
   enhancer.setCallbackType(MethodInterceptor.class);

   // Ideally create enhanced FactoryBean proxy without constructor side effects,
   // analogous to AOP proxy creation in ObjenesisCglibAopProxy...
   Class<?> fbClass = enhancer.createClass();
   Object fbProxy = null;

   if (objenesis.isWorthTrying()) {
      try {
         fbProxy = objenesis.newInstance(fbClass, enhancer.getUseCache());
      }
      catch (ObjenesisException ex) {
         logger.debug("Unable to instantiate enhanced FactoryBean using Objenesis, " +
               "falling back to regular construction", ex);
      }
   }

   if (fbProxy == null) {
      try {
         fbProxy = ReflectionUtils

.........................................

 

再看下BeanFactoryAwareMethodInterceptor   //为方法设置注入beanfactory

 *
 */
private static class BeanFactoryAwareMethodInterceptor implements MethodInterceptor, ConditionalCallback {

   @Override
   @Nullable
   public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
      Field field = ReflectionUtils.findField(obj.getClass(), BEAN_FACTORY_FIELD);
      Assert.state(field != null, "Unable to find generated BeanFactory field");
      field.set(obj, args[0]);

      // Does the actual (non-CGLIB) superclass implement BeanFactoryAware?
      // If so, call its setBeanFactory() method. If not, just exit.
      if (BeanFactoryAware.class.isAssignableFrom(ClassUtils.getUserClass(obj.getClass().getSuperclass()))) {
         return proxy.invokeSuper(obj, args);
      }
      return null;
   }

   @Override
   public boolean isMatch(Method candidateMethod) {
      return (candidateMethod.getName().equals("setBeanFactory") &&
            candidateMethod.getParameterCount() == 1 &&
            BeanFactory.class == candidateMethod.getParameterTypes()[0] &&
            BeanFactoryAware.class.isAssignableFrom(candidateMethod.getDeclaringClass()));
   }
}


/**
 * Intercepts the invocation of any {@link Bean}-annotated methods in order to ensure proper
 * handling of bean semantics such as scoping and AOP proxying.
 * @see Bean
 * @see ConfigurationClassEnhancer
 */
private static class BeanMethodInterceptor implements MethodInterceptor, ConditionalCallback {

   /**
    * Enhance a {@link Bean @Bean} method to check the supplied BeanFactory for the
    * existence of this bean object.
    * @throws Throwable as a catch-all for any exception that may be thrown when invoking the
    * super implementation of the proxied method i.e., the actual {@code @Bean} method
    */
   @Override
   @Nullable
   public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
            MethodProxy cglibMethodProxy) throws Throwable {

      ConfigurableBeanFactory beanFactory = getBeanFactory(enhancedConfigInstance);
      String beanName = BeanAnnotationHelper.determineBeanNameFor(beanMethod);

      // Determine whether this bean is a scoped-proxy
      Scope scope = AnnotatedElementUtils.findMergedAnnotation(beanMethod, Scope.class);
      if (scope != null && scope.proxyMode() != ScopedProxyMode.NO) {
         String scopedBeanName = ScopedProxyCreator.getTargetBeanName(beanName);
         if (beanFactory.isCurrentlyInCreation(scopedBeanName)) {
            beanName = scopedBeanName;
         }
      }

      // To handle the case of an inter-bean method reference, we must explicitly check the
      // container for already cached instances.

      // First, check to see if the requested bean is a FactoryBean. If so, create a subclass
      // proxy that intercepts calls to getObject() and returns any cached bean instance.
      // This ensures that the semantics of calling a FactoryBean from within @Bean methods
      // is the same as that of referring to a FactoryBean within XML. See SPR-6602.
      if (factoryContainsBean(beanFactory, BeanFactory.FACTORY_BEAN_PREFIX + beanName) &&
            factoryContainsBean(beanFactory, beanName)) {
         Object factoryBean = beanFactory.getBean(BeanFactory.FACTORY_BEAN_PREFIX + beanName);
         if (factoryBean instanceof ScopedProxyFactoryBean) {
            // Scoped proxy factory beans are a special case and should not be further proxied
         }
         else {
            // It is a candidate FactoryBean - go ahead with enhancement
            return enhanceFactoryBean(factoryBean, beanMethod.getReturnType(), beanFactory, beanName);
         }
      }

      if (isCurrentlyInvokedFactoryMethod(beanMethod)) {
         // The factory is calling the bean method in order to instantiate and register the bean
         // (i.e. via a getBean() call) -> invoke the super implementation of the method to actually
         // create the bean instance.
         if (logger.isWarnEnabled() &&
               BeanFactoryPostProcessor.class.isAssignableFrom(beanMethod.getReturnType())) {
            logger.warn(String.format("@Bean method %s.%s is non-static and returns an object " +
                        "assignable to Spring's BeanFactoryPostProcessor interface. This will " +
                        "result in a failure to process annotations such as @Autowired, " +
                        "@Resource and @PostConstruct within the method's declaring " +
                        "@Configuration class. Add the 'static' modifier to this method to avoid " +
                        "these container lifecycle issues; see @Bean javadoc for complete details.",
                  beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName()));
         }
         return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
      }

      return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
   }

...............................................

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值