在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
那么调用将被传递给原来的方法。