上一节简单使用SpringBoot完成了HelloWorld,这一节深入介绍如何使用SpringBoot进行容器管理,比如在容器中注册组件、读取资源等
2. 容器管理
2.1 使用配置类注册组件
在Spring中,我们使用Spring的xml配置文件注册bean,往容器里面添加组件
<bean id="person" class="com.lin.pojo.Person">
<property name="name" value="Mike"/>
</bean>
在SpringBoot中已经摒弃xml配置文件,从而使用Java配置类的方式进行组件的注册,步骤如下
①创建一个MyConfig类,并用注解@Configuration修饰
@Configuration//说明这是一个配置类
public class MyConfig {
}
②在配置类中用函数替代标签,用@Bean修饰方法,默认以方法名作为组件名,返回类型作为组件class,返回值作为容器中的实例,使用@Bean(“组件名”)可以指定组件名
@Configuration
public class MyConfig {
//等同于注册了一个id是person,类型是com.lin.pojo.Person,实例是new Person("Mike")的bean
@Bean //@Bean("组件名")可以指定组件名
public Person person(){
return new Person("Mike");
}
}
③在主程序中获取组件
@SpringBootApplication
public class Application {
public static void main(String[] args)
{
ConfigurableApplicationContext run = SpringApplication.run(Application.class, args);
Object person = run.getBean("person");//通过id获取
Person bean = run.getBean(Person.class);//通过类型获取
System.out.println(person==bean);//true说明是单例的
}
}
2.2 使用自动扫描注册组件
在2.1中相当于是手动注册了组件,另外还有一种方法就是让SpringBoot自动扫描
①在要添加的组件的类上使用@Component注解
@Component
public class Person {
@Value("Mike") //使用@Value注入值,底层通过反射注入的
String name;
}
②在主程序中获取组件
@SpringBootApplication
public class Application {
public static void main(String[] args)
{
ConfigurableApplicationContext run = SpringApplication.run(Application.class, args);
Object person = run.getBean("person");
Person bean = run.getBean(Person.class);
System.out.println(person==bean);//同样是单例的
}
}
为什么没有显式配置扫描路径,就能自动扫描?因为在主程序注解@SpringBootApplication中已经默认配置好了。原理如下:
进入@SpringBootApplication中查看,发现还有三个注解用来修饰@SpringBootApplication,其中**@ComponentScan代表的扫描路径就是主程序所以在的包,以及下面的子包**

那么,在主程序中用这三个注解替换@SpringBootApplication是可行的
//下面三个注解连用时,与@SpringBootApplication等效!!
@SpringBootConfiguration//代表这是SpringBoot的配置类
@EnableAutoConfiguration//将所有符合条件的@Configuration配置都加载到IoC容器。
@ComponentScan("com.lin")//这里写的是主程序所在的包名
public class Application {
public static void main(String[] args)
{
ConfigurableApplicationContext run = SpringApplication.run(Application.class, args);
Object person = run.getBean("person");
Person bean = run.getBean(Person.class);
}
}
2.3使用@Import注册组件
@Import可以作用在任何一个已经在IOC容器中的组件上,作用是把Class类型数组里面的类注册到容器中

可以将@Import应用在主程序类上,因为Application类本身也是一个组件,由@SpringBootApplication注册了
@SpringBootApplication
@Import({Person.class})//注册Person这个组件
public class Application {
public static void main(String[] args)
{
ConfigurableApplicationContext run = SpringApplication.run(Application.class, args);
Person person = run.getBean("com.lin.pojo.Person",Person.class);//id是全类名
Person bean = run.getBean(Person.class);
bean.setName("Mike");
person.setName("Mike");
System.out.println(bean==person);
}
}
2.5 三种注册组件方法如何选择?
最佳实践:大多是情况下都是使用2.1中配置类,也可以使用更便捷的2.2中的自动扫描。
如果要引入第三方包中的组件,就要使用2.3的@Import。因为不可能去修改第三方包的源码,在上面加@Component
2.6使用@ImportResource导入原生配置文件
虽然在SpringBoot推荐使用配置类的形式注册组件,但是如果想使用原来的Spring.xml配置文件注册的bean,也是可行的。只要在任意一个已经在IOC容器中的组件上使用@ImportResource
@SpringBootApplication
@ImportResource("classpath:/beans.xml")//导入配置文件
public class Application {
public static void main(String[] args)
{
ConfigurableApplicationContext run = SpringApplication.run(Application.class, args);
Person person = run.getBean("person",Person.class);
Person bean = run.getBean(Person.class);
}
}
2.7 与properties文件绑定的两种方法
如何读取properties,并且将其中内容封装到JavaBean中?以前是通过下面的java代码,先加载然后遍历再封装
public class getProperties {
public static void main(String[] args) throws FileNotFoundException, IOException {
Properties pps = new Properties();
pps.load(new FileInputStream("a.properties"));//加载文件
Enumeration enum1 = pps.propertyNames();//得到配置文件key
while(enum1.hasMoreElements()) {//遍历
String strKey = (String) enum1.nextElement();
String strValue = pps.getProperty(strKey);
System.out.println(strKey + "=" + strValue);
//封装到JavaBean。
}
}
}
在SpringBoot中可以**直接使用注解将配置文件与Bean绑定起来****,比如在application.properties中写入
//person对应的是注解的prefix属性,name对应Bean中的属性
person.name=test
2.7.1 使用@ConfigurationProperties
该注解必须用在已经注册于IOC容器的组件上,就是说在用了前面任意一种添加组件方法的前提下,使用该注解才有效,且注解是通过set注入的
@ConfigurationProperties(prefix = "person") //前提:Person已经注册了
public class Person {
String name;
public Person(String name) {
this.name = name;
}
public Person() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
System.out.println("调用了set");
}
}
@SpringBootApplication
public class Application {
public static void main(String[] args)
{
ConfigurableApplicationContext run = SpringApplication.run(Application.class, args);
Person person = run.getBean("person",Person.class);
System.out.println(person); //Person{name='test'}
}
在这里我选择通过配置类(2.1)中的方法注册Person类,然后再使用@ConfigurationProperties,发现先会调用有参构造,然后再通过set注入properties中的值,所以最后name=“test”
2.7.2 使用@EnableConfigurationProperties + @ConfigurationProperties
如2.5.1所示,在使用了@ConfigurationProperties前提下,直接在配置类上使用@EnableConfigurationProperties,有两个作用:首先将类注册,其次绑定properties文件
@Configuration
//在配置类上使用,有两个作用:首先是注册Person,然后再绑定
@EnableConfigurationProperties(Person.class)
public class MyConfig {
//不需要@Bean注册了
}
@SpringBootApplication
public class Application {
public static void main(String[] args)
{
ConfigurableApplicationContext run = SpringApplication.run(Application.class, args);
//通过@EnableConfigurationProperties注册的组件名默认是:类名小写-全类名
Person person = run.getBean("person-com.lin.pojo.Person",Person.class);
Person bean = run.getBean(Person.class);
System.out.println(person);//Person{name='test'}
System.out.println(bean);//Person{name='test'}
}
}
2.8 使用Lombok简化JavaBean开发
Lombok可以在编译时动态生成类的getter/setter方法、有参/无参构造函数、toString()、equals()与hashCode(),与下图等价

导入Lombok依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
修改JavaBean为
@ConfigurationProperties(prefix = "person")
@Data//生成getter和setter
@AllArgsConstructor//生成全参构造器
@NoArgsConstructor//生成无参构造器
@ToString//生成toString()
@EqualsAndHashCode//生成equals()与hashCode()
public class Person {
String name;
}
2.9 使用Spring Initailizr(项目初始化向导)
会自动导入相关依赖,以及创建好相关的包结构



983

被折叠的 条评论
为什么被折叠?



