@SpringBootConfiguration继承自@Configuration,二者功能也一致,标注当前类是配置类,并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到spring容器中,并且实例名就是方法名。
@Target({ElementType.TYPE}) //表明注解的作用目标是接口、类、枚举
@Retention(RetentionPolicy.RUNTIME) // 表示注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Documented //说明该注解将被包含在javadoc中
@Configuration //spring 注解,用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器
public @interface SpringBootConfiguration {
@AliasFor(
annotation = Configuration.class
)
boolean proxyBeanMethods() default true;
}
SpringBootConfiguration :
标注这个类是一个配置类;
它只是@Configuration注解的派生注解;
它与@Configuration注解的功能一致;
只不过@SpringBootConfiguration是springboot的注解,而@Configuration是spring的注解。
@SpringBootConfiguration
public class DemoConfig {
@Bean // 依赖关系
public Map createMap(){
Map map = new HashMap();
System.out.println("创建map");
map.put("username","zhoupeng");
map.put("age",24);
return map;
}
@Bean
public Student student() {
Student std = new Student();
System.out.println("创建Student");
std.setName("zhoupeng");
std.setClazz("2020");
return std;
}
@Bean
public Teacher teacher() {
Teacher tec = new Teacher();
System.out.println("创建Teacher");
tec.setName("Teacher Zhang");
tec.setMajoringSubject("mathematics");
return tec;
}
}
@Configuration
可以理解为一个Configuration就是对应的一个Spring的xml版的容器;一个被@Configuration标注的类,相当于一个applicationContext.xml文件
@Component、@Bean是两种使用注解来定义bean的方式。
@Component(和@Service和@Repository)用于自动检测和使用类路径扫描自动配置bean。注释类和bean之间存在隐式的一对一映射(即每个类一个bean)。
@Bean用于显式声明单个bean,而不是让Spring像上面那样自动执行它。它将bean的声明与类定义分离,并允许您精确地创建和配置bean。
@Bean则常和@Configuration注解搭配使用:
@Configuration
public class DemoConfig {
@Bean
public Map createMap(){
Map map = new HashMap();
System.out.println("创建map");
map.put("username","zhoupeng");
map.put("age",24);
return map;
}
@Bean
public Student student() {
Student std = new Student();
System.out.println("创建Student");
std.setName("zhoupeng");
std.setClazz("2020");
return std;
}
@Bean
public Teacher teacher() {
Teacher tec = new Teacher();
System.out.println("创建Teacher");
tec.setName("Teacher Zhang");
tec.setMajoringSubject("mathematics");
return tec;
}
}
都可以使用@Autowired或者@Resource注解注入;
@Bean注解告诉Spring这个方法将会返回一个对象,这个对象要注册为Spring应用上下文中的bean。通常方法体中包含了最终产生bean实例的逻辑。
两者的区别:
如果想将第三方的类变成组件,没有源代码,也就没办法使用@Component进行自动配置,这种时候使用@Bean就比较合适了。
另外@Bean注解的方法返回值是对象,可以在方法中为对象设置属性。
SpringBootApplication注解包含了SpringBootConfiguration 注解
@SpringBootApplication
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {}
直接在SpringBootApplication注解作用的类上来注册一个Bean
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
public class App {
@Bean
public Teacher teach() {
Teacher tec = new Teacher();
System.out.println("Creating Teacher use SpringBootApplication");
tec.setName("Teacher Bai");
tec.setMajoringSubject("English");
return tec;
}
public static void main(String[] args) {
System.out.println( "Hello SpringBoot!" );
ConfigurableApplicationContext context = SpringApplication.run(App.class, args);
Map map = (Map) context.getBean("createMap"); //注意这里直接获取到这个方法bean
int age = (int) map.get("age");
System.out.println("age=="+age);
Student std = (Student) context.getBean("student");
System.out.println(String.format("%s is a student in class NO.%s", std.getName(), std.getClazz()));
Teacher tec = (Teacher) context.getBean("teacher");
System.out.println(String.format("%s majored in %s", tec.getName(), tec.getMajoringSubject()));
Teacher teach = (Teacher) context.getBean("teach");
System.out.println(String.format("%s majored in %s", teach.getName(), teach.getMajoringSubject()));
}
}
运行效果
Hello SpringBoot!
2020-08-04 12:42:21.659 INFO 8808 --- [ main] com.zpnlp.demo.App : Starting App using Java 14.0.2 on DESKTOP-BKDE1EB with PID 8808 (F:\code\java\spring-boot\target\classes started by 17888 in F:\code\java\spring-boot)
2020-08-04 12:42:21.660 INFO 8808 --- [ main] com.zpnlp.demo.App : No active profile set, falling back to default profiles: default
2020-08-04 12:42:22.247 INFO 8808 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2020-08-04 12:42:22.252 INFO 8808 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-08-04 12:42:22.252 INFO 8808 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.36]
2020-08-04 12:42:22.328 INFO 8808 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-08-04 12:42:22.328 INFO 8808 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 643 ms
创建map
创建Student
创建Teacher
Creating Teacher use SpringBootApplication
2020-08-04 12:42:22.505 INFO 8808 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-08-04 12:42:22.546 INFO 8808 --- [ main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
2020-08-04 12:42:22.678 INFO 8808 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2020-08-04 12:42:22.685 INFO 8808 --- [ main] com.zpnlp.demo.App : Started App in 1.216 seconds (JVM running for 1.593)
age==24
zhoupeng is a student in class NO.2020
Teacher Zhang majored in mathematics
Teacher Bai majored in English