创建SpringBoot项目 test0905
,全部使用默认设置。
创建包 com.example.test0905.pojo
,并创建如下POJO:
Axe
:Axe接口;StoneAxe
:Axe实现类;SteelAxe
:Axe实现类;Person
:Person持有Axepackage com.example.test0905.pojo;
public interface Axe {
public void chop();
}
package com.example.test0905.pojo;
import org.springframework.stereotype.Component;
@Component
public class StoneAxe implements Axe{
public StoneAxe() {
System.out.println("StoneAxe constructor!");
}
@Override
public void chop() {
System.out.println("Stone axe!");
}
}
package com.example.test0905.pojo;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@Component
@Primary
public class SteelAxe implements Axe{
public SteelAxe() {
System.out.println("SteelAxe constructor!");
}
@Override
public void chop() {
System.out.println("Steel axe!");
}
}
package com.example.test0905.pojo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Person {
private String name;
private Axe axe;
public void useAxe() {
System.out.println("I am " + name);
axe.chop();
}
@Autowired
public Person(@Value("Tom") String name, Axe axe) {
System.out.println("Person constructor!");
this.name = name;
this.axe = axe;
}
}
默认生成的主程序代码如下:
package com.example.test0905;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Test0905Application {
public static void main(String[] args) {
SpringApplication.run(Test0905Application.class, args);
}
}
SpringBoot程序的入口是 SpringApplication.run()
方法:
@SpringBootApplication
注解所修饰,也就是主配置类;ConfigurableApplicationContext
对象,即Spring容器;修改代码如下:
public static void main(String[] args) {
var ctx = SpringApplication.run(Test0905Application.class, args);
System.out.println("=====================================");
var person = ctx.getBean("person", Person.class);
person.useAxe();
}
运行程序,结果如下:
SteelAxe constructor!
Person constructor!
StoneAxe constructor!
......
=====================================
I am Tom
Steel axe!
可见,默认情况下,在初始化Spring时,会初始化所有singleton的bean。
public static void main(String[] args) {
var application = new SpringApplication(Test0905Application.class);
application.setLazyInitialization(true);
application.setBannerMode(Banner.Mode.OFF);
var ctx = application.run(args);
System.out.println("=====================================");
var person = ctx.getBean("person", Person.class);
person.useAxe();
}
运行程序,结果如下:
=====================================
SteelAxe constructor!
Person constructor!
I am Tom
Steel axe!
本例中,显式的实例化了一个 SpringApplication
对象,然后调用其 run()
方法运行,和前面的方式很类似。在运行之前,可以配置该实例对象。本例中,配置了懒加载,并且设置为不显示banner。
懒加载的效果:在初始化Spring容器时,并没有实例化任何bean,而是在 getBean()
的时候才实例化 Person
,因为把 SteelAxe
注入了 Person
,所以 SteelAxe
会在 Person
前实例化。 StoneAxe
没有被实例化。
public static void main(String[] args) {
var ctx = new SpringApplicationBuilder().sources(Test0905Application.class)
.bannerMode(Banner.Mode.OFF)
.lazyInitialization(true)
.run(args);
System.out.println("=====================================");
var person = ctx.getBean("person", Person.class);
person.useAxe();
}
运行程序,结果如下:
=====================================
SteelAxe constructor!
Person constructor!
I am Tom
Steel axe!
本例和前面的例子类似,只不过是显式的实例化了一个 SpringApplicationBuilder
对象,然后通过流式API的方式来配置,最后调用其 run()
方法运行。本例中,配置了懒加载,并且设置为不显示banner。
注: new
的优先级比 .
高,所以 new SpringApplicationBuilder().sources(Test0905Application.class)
等同于 (new SpringApplicationBuilder()).sources(Test0905Application.class)
,括号可以省略。