## 通常模式 Spring 对 `@Bean`注解的要求是必须是可重写,所以`public`,`protected`,`package`这几种修饰都是可以的。 简单验证: import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class Config { @Bean RestTemplate restTemplate() { return new RestTemplate(); } } import org.springframework.web.client.RestTemplate; public class MyService { RestTemplate restTemplate; public MyService(RestTemplate restTemplate) { this.restTemplate = restTemplate; } public String getHelloWorld() { return restTemplate.getForObject("http://httpbin.org/ip", String.class); } } import org.springframework.context.ApplicationContext; import org.springframework.web.client.RestTemplate; public class Main { public static void main(String[] args) { ApplicationContext context = new org.springframework.context.annotation.AnnotationConfigApplicationContext(Config.class); MyService myService = new MyService(context.getBean(RestTemplate.class)) ; System.out.println("Hello world from: "+myService.getHelloWorld() ); } } 运行输出: Hello world from: { "origin": "114.251.201.2" } 反过来说, `private` 是不可以的  另外, `static` 方法也是可以被 `@Bean` 修饰的。 摘一段源码文档: > Typically, @Bean methods are declared within @Configuration classes. In this > case, bean methods may reference other @Bean methods in the same class by > calling them directly. This ensures that references between beans are > strongly typed and navigable. Such so-called 'inter-bean references' are > guaranteed to respect scoping and AOP semantics, just like getBean() lookups > would. These are the semantics known from the original 'Spring JavaConfig' > project which require CGLIB subclassing of each such configuration class at > runtime. As a consequence, @Configuration classes and their factory methods > must not be marked as final or private in this mode. 最后一句机翻一下: > 这些是原始“Spring JavaConfig”项目中已知的语义,需要在运行时对每个此类配置类进行 CGLIB > 子类化。因此,在此模式下,不得将@Configuration类及其工厂方法标记为最终或私有。 所以通常模式 `final` 和 `private` 修饰是不可以的。 ## 小模式(Lite Mode) `@Bean` 直接定义的 `@Component` \ `@Service` 里: import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; @Component public class MyService { @Autowired RestTemplate restTemplate; public String getHelloWorld() { return restTemplate.getForObject("http://httpbin.org/ip", String.class); } @Bean private RestTemplate restTemplate() { return new RestTemplate(); } } import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(MyService.class); MyService myService = context.getBean(MyService.class); System.out.println("Hello world from: "+myService.getHelloWorld() ); } } 这种情况下,定义成 `private` 是可以。 ## 总结 小模式下可以为`private`, 通常模式下不可以为`private`, 限制更少的 `package` 都是可以的