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.
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() );
}
}
通常模式
Spring 对
@Bean
注解的要求是必须是可重写,所以public
,protected
,package
这几种修饰都是可以的。简单验证:
运行输出:
反过来说,

private
是不可以的另外,
static
方法也是可以被@Bean
修饰的。摘一段源码文档:
最后一句机翻一下:
所以通常模式
final
和private
修饰是不可以的。小模式(Lite Mode)
@Bean
直接定义的@Component
\@Service
里:这种情况下,定义成
private
是可以。总结
小模式下可以为
private
, 通常模式下不可以为private
, 限制更少的package
都是可以的