众所周知,Spring Boot已然是目前Java业界比较热门的轻量级框架,它抛去了Spring原本的复杂和繁琐的XML配置,整合了常用的开发插件,使用Java类的配置化,使框架配置极简化,可以很轻松的部署和启动一个微服务。
由于Spring Boot是在Spring框架的基础上搭建的,要全面理解一个新晋框架的知识,就一定要了解它从繁入简的过程。所以我们首先从Spring的发展历史开始了解,随着一步一步的对框架的优化和补充,进而我们就会明白Spring Boot诞生的原因。
一、Spring1.x时代
在Spring1.x时代,所有的配置信息都是通过XML来配置的,包括Spring的IOC特性,都是需要将要注入的Bean信息全部配置在XML中。当项目变的十分庞大的时候,就需要将许多的XML文件进行一个一个的分类,才能便于管理。然后开发Java类的时候,也需要不停的切换Java类和XML进行编写,也比较繁琐。
下面是一个Spring1.x的纯XML配置的例子:
这里使用类来模拟手机和配件的关系,Screen是屏幕类,Battery是电池类,Phone是手机类:
package cn.com.spring.test.bean;
public class Screen {
private String size;//尺寸
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
@Override
public String toString() {
return "size:"+size;
}
}
package cn.com.spring.test.bean;
public class Battery {
private String type;//类型
private String capacity;//容量
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getCapacity() {
return capacity;
}
public void setCapacity(String capacity) {
this.capacity = capacity;
}
@Override
public String toString() {
return "type:"+type+" capacity:"+capacity;
}
}
package cn.com.spring.test.bean;
public class Phone {
private Screen screen;
private Battery battery;
public Screen getScreen() {
return screen;
}
public void setScreen(Screen screen) {
this.screen = screen;
}
public Battery getBattery() {
return battery;
}
public void setBattery(Battery battery) {
this.battery = battery;
}
@Override
public String toString() {
return "screen:"+screen+"\n battery:"+battery;
}
}
然后我们在beans.xml中配置三个bean以及对应的参数注入和实体注入:
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="screen" class="cn.com.spring.test.bean.Screen">
<property name="size" value="1080*720"/>
</bean>
<bean id="battery" class="cn.com.spring.test.bean.Battery" scope="singleton">
<property name="type" value="锂电池"/>
<property name="capacity" value="3400毫安"/>
</bean>
<bean id="phone" class="cn.com.spring.test.bean.Phone">
<property name="battery" ref="battery"/>
<property name="screen" ref="screen" />
</bean>
</beans>
然后编写一个测试类,看一下最终phone的注入类打印的结果:
package cn.com.spring.test.main;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.com.spring.test.bean.Phone;
public class SpringTest {
public static void main(String[] args) {
String[] locations = {"beans.xml"};
ApplicationContext ctx = new ClassPathXmlApplicationContext(locations);
Phone phone = (Phone) ctx.getBean("phone");
System.out.println(phone);
}
}
结果:
正如我们上面在beans中注入的一样,screen和battery在xml中注入了参数,phone在xml中注入了成员变量的实体类实现。
以上就是Spring1.x时代的主要配置方式。
二、Spring2.x时代
随着JDK1.5的到来,Spring迎来了2.x时代,因为JDK1.5新增了对注解的支持。在Spring2.x中可以使用注解对Bean进行声明和注入,大大的减少了XML配置文件,也大大简化了项目的开发。
我们把刚才的phone、screen和battery的xml配置模式改为注解模式:
package cn.com.spring.test.bean;
import org.springframework.beans.factory.annotation.Autowired;
public class Phone {
@Autowired
private Screen screen;
@Autowired
private Battery battery;
@Override
public String toString() {
return "screen:"+screen+"\n battery:"+battery;
}
}
上面将Phone类中的get和set方法删除,在两个成员变量上添加了@Autowired注解。当 Spring容器启动时,AutowiredAnnotationBeanPostProcessor将扫描Spring容器中所有Bean,当发现Bean中拥有@Autowired注释时就找到和其匹配(默认按类型匹配)的 Bean,并注入到对应的地方中去。相应的xml中就无需对Phone类进行注入了:
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<!-- BeanPostProcessor对标注 @Autowired的Bean进行自动注入 -->
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<bean id="screen" class="cn.com.spring.test.bean.Screen">
<property name="size" value="1080*720"/>
</bean>
<bean id="battery" class="cn.com.spring.test.bean.Battery" scope="singleton">
<property name="type" value="锂电池"/>
<property name="capacity" value="3400毫安"/>
</bean>
<bean id="phone" class="cn.com.spring.test.bean.Phone"/>
</beans>
运行测试类,和上面结果是一样的。
最后,在Spring2.x时代,讨论的最多的问题就是:是应该使用XML还是使用注解呢?
该问题有一个最佳实践:
1、应用的基本配置使用XML,比如:数据源、资源文件等。
2、业务开发使用注解,比如:Service中注入bean等。
三、Spring3.x到Spring4.x时代
从Spring3.x开始提供了Java的配置方式,使用Java配置方式可以更好的理解你配置的Bean。目前我们正处于这个时代,并且Spring4.x和Spring Boot都推荐使用Java配置的方式。Java配置的方式依赖于两个注解,分别是@Configuration和@Bean:
1、@Configuration 作用于类上,相当于一个xml配置文件;
2、@Bean 作用于方法上,相当于xml配置中的<bean>;
我们将之前的Phone、Screen以及Battery都使用Java配置方式来实现注入:
package cn.com.spring.test.conf;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import cn.com.spring.test.bean.Battery;
import cn.com.spring.test.bean.Phone;
import cn.com.spring.test.bean.Screen;
@Configuration
public class AppConfig {
@Bean
public Screen screen() {
Screen screen = new Screen();
screen.setSize("1080*720");
return screen;
}
@Bean
public Battery battery() {
Battery battery = new Battery();
battery.setType("锂电池");
battery.setCapacity("3400毫安");
return battery;
}
@Bean
public Phone phone() {
return new Phone();
}
}
这种配置方式和下面的XML没有任何区别:
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<!-- BeanPostProcessor对标注 @Autowired的Bean进行自动注入 -->
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<bean id="screen" class="cn.com.spring.test.bean.Screen">
<property name="size" value="1080*720"/>
</bean>
<bean id="battery" class="cn.com.spring.test.bean.Battery" scope="singleton">
<property name="type" value="锂电池"/>
<property name="capacity" value="3400毫安"/>
</bean>
<bean id="phone" class="cn.com.spring.test.bean.Phone"/>
</beans>
注:在Phone类中依然使用的@Autowired对screen和battery类进行注入。
测试方法:
package cn.com.spring.test.main;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import cn.com.spring.test.bean.Phone;
import cn.com.spring.test.conf.AppConfig;
public class SpringTest {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
Phone phone = ctx.getBean(Phone.class);
System.out.println(phone);
}
}
测试结果:
这里使用AnnotationConfigApplicationContext读取Java配置,类似于ClassPathXmlApplicationContext读取之前的XML配置文件路径。
测试结果和之前使用XML的配置一样,使用Java配置使得开发者可以更好的理解配置。
至此,Spring的基本发展历程就介绍完毕了,下一篇我们重点来介绍Spring的Java配置方式。
参考:
传智播客《Spring Boot实战与原理分析》视频课程
(https://pan.baidu.com/s/1o9M2bGI 密码:jxg8)
https://blog.csdn.net/sinat_38239454/article/details/72636816
https://www.cnblogs.com/qlqwjy/p/7967679.html
转载请注明出处:https://blog.csdn.net/acmman/article/details/81214092