在Spring javaconfiguration中调用@Bean注释的方法

我很好奇Spring注入是如何处理用@Bean注解来调用方法的。 如果我在方法上放了一个@Bean注解,并返回一个实例,我明白这告诉spring通过调用方法并获取返回的实例来创build一个bean。 但是,有时候这个bean必须用来连接其他bean或设置其他代码。 通常的做法是调用@Bean注释的方法来获取实例。 我的问题是,为什么这不会导致有多个bean浮动的实例呢?

例如,请参阅下面的代码(来自另一个问题)。 entryPoint()方法用@Bean注释,所以我想可以想象spring将创build一个新的BasicAuthenticationEntryPoint实例作为bean。 然后,我们在configure块中再次调用了entryPoint() ,但是似乎就像entryPoint()返回了这个bean实例一样,并没有多次调用(我试过logging,只有一个日志条目)。 可能我们可以在configuration的其他部分多次调用entryPoint() ,并且总是会得到相同的实例。 我的理解是正确的吗? spring做了一些用@Bean注释的方法的魔法重写吗?

 @Bean public BasicAuthenticationEntryPoint entryPoint() { BasicAuthenticationEntryPoint basicAuthEntryPoint = new BasicAuthenticationEntryPoint(); basicAuthEntryPoint.setRealmName("My Realm"); return basicAuthEntryPoint; } @Override protected void configure(HttpSecurity http) throws Exception { http .exceptionHandling() .authenticationEntryPoint(entryPoint()) .and() .authorizeUrls() .anyRequest().authenticated() .and() .httpBasic(); } 

是的,spring做了一些魔术 。 检查Spring文档 :

所有@Configuration类在CGLIB启动时被分类。 在子类中,child方法在调用父方法并创build一个新实例之前首先检查容器是否有caching的(范围)bean。

这意味着您对@Bean方法的调用通过CGLIB进行代理,因此将返回该bean的caching版本(不会创build新的)。

@Bean s的默认范围是@Bean ,如果你指定一个不同的范围如PROTOTYPE那么调用将被传递给原来的方法。