系统要求
- Java 8
- Maven 3.3+
- IntelliJ IDEA 2019.1.2
Maven配置文件
新添内容:
1.1、HelloWorld项目nexus-aliyun central Nexus aliyun http://maven.aliyun.com/nexus/content/groups/public jdk-1.8 true1.8 1.8 1.8 1.8
需求:浏览发送/hello请求,响应 “Hello,Spring Boot 2”创建maven工程
父:spring-boot-starter-parent
引入依赖:
- web支持:spring-boot-starter-web
org.springframework.boot spring-boot-starter-parent2.3.4.RELEASE org.springframework.boot spring-boot-starter-web
创建主程序
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}
编写业务
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@RequestMapping("/hello")
public String handle01(){
return "Hello, Spring Boot 2!";
}
}
运行&测试
运行MainApplication类
浏览器输入http://localhost:8080/hello,将会输出Hello!。
设置配置
maven工程的resource文件夹中创建application.properties文件。
# 设置端口号
server.port=8888
更多配置信息
打包部署
之前是打成war包,然后放到tomcat中运行。
现在: 在pom.xml添加
org.springframework.boot
spring-boot-maven-plugin
在IDEA的Maven插件上点击运行 clean 、package,把helloworld工程项目的打包成jar包,
打包好的 jar 包被生成在helloworld工程项目的target文件夹内。
用cmd运行java -jar boot-01-helloworld-1.0-SNAPSHOT.jar,既可以运行helloworld工程项目。
将jar包直接在目标服务器执行即可。
1.2、Sprigboot项目总结:1、引入依赖
org.springframework.boot spring-boot-starter-parent2.3.4.RELEASE org.springframework.boot spring-boot-starter-web
2、创建主程序
@SpringBootApplication
@Slf4j
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class,args);
log.info("系统正常启动");
}
}
3、编写业务
@RestController //@RestController = @Controller + @ResponseBody
public class HelloController {
@RequestMapping("/hello")
public String handle01(){
return "hello";
}
}
4、测试
直接运行Main
5、简化配置
application.properties:
server.port=8888
6、简化部署
org.springframework.boot spring-boot-maven-plugin
把项目打成jar 包,直接在目标服务器执行就行。
1.3、自动配置管理 依赖管理 1.3.1、父项目做依赖管理管理依赖的版本号,默认引入的引来可以不写版本号,有默认值,当然也可以写。
1.3.2、开发导入starter场景启动器依赖管理上面项目的父项目如下: org.springframework.boot spring-boot-starter-parent2.3.4.RELEASE 它几乎声明了所有开发中常用的依赖的版本号,自动版本仲裁机制 org.springframework.boot spring-boot-dependencies2.3.4.RELEASE
- 见到很多 spring-boot-starter-* : *就某种场景
- 只要引入starter,这个场景的所有常规需要的依赖我们都自动引入
- 更多SpringBoot所有支持的场景
- 见到的 *-spring-boot-starter: 第三方为我们提供的简化开发的场景启动器。
1.3.3、无需关注版本号,直接版本仲裁所有场景启动器最底层的依赖
org.springframework.boot
spring-boot-starter
2.3.4.RELEASE
compile
- 引入依赖默认都可以不写版本
- 引入非版本仲裁的jar,要写版本号
- 查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。
- 在当前项目里面重写配置,如下面的代码,则可以替代默认的版本号。
5.1.43
IDEA快捷键:
- option + command + U:以图的方式显示项目中依赖之间的关系。
引入spring-boot-starter-web依赖,会默认包含:
spring-boot-starter-tomcat、spring-web、spring-webmvc
1.3.1、自动配好Tomcat
- 引入Tomcat依赖。
- 配置Tomcat
org.springframework.boot
spring-boot-starter-tomcat
2.3.4.RELEASE
compile
1.3.2、自动配好SpringMVC
- 引入SpringMVC全套组件
- 自动配好SpringMVC常用组件(功能)
1.3.3、自动配好Web常用功能:字符编码问题
- SpringBoot帮我们配置好了所有web开发的常见场景
public static void main(String[] args) {
//1、返回我们IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);//2、查看容器里面的组件
String[] names = run.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
}
1.3.4、默认的包结构
- 主程序(MainApplication)所在包及其下面的所有子包里面的组件都会被默认扫描进来
- 无需以前的包扫描配置
- 想要改变扫描路径
- @SpringBootApplication(scanbasePackages=“com.lun”)
- 或者
- @ComponentScan 指定扫描路径
@SpringBootApplication
等同于
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.lun")
1.3.4、各种配置拥有默认值
- 默认配置最终都是映射到某个类上,如:MultipartProperties
- 配置文件的值最终会绑定每个类上,这个类会在容器中创建对象
- 非常多的starter
- 引入了哪些场景这个场景的自动配置才会开启
- SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面
- @Configuration(proxyBeanMethod="true")
- @Bean:方法名就是bean id,返回值是bean实例,返回类型是bean类型
- 配置类本身也是组件:是一个代理组件
Full模式与Lite模式
@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {
@Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
public User user01(){
User zhangsan = new User("zhangsan", 18);
//user组件依赖了Pet组件
zhangsan.setPet(tomcatPet());
return zhangsan;
}
@Bean("tom")
public Pet tomcatPet(){
return new Pet("tomcat");
}
}
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.atguigu.boot")
public class MainApplication {
public static void main(String[] args) {
//1、返回我们IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
//2、查看容器里面的组件
String[] names = run.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
//3、从容器中获取组件
Pet tom01 = run.getBean("tom", Pet.class);
Pet tom02 = run.getBean("tom", Pet.class);
System.out.println("组件:"+(tom01 == tom02));
//4、com.atguigu.boot.config.MyConfig$$EnhancerBySpringCGLIB$$51f1e1ca@1654a892
MyConfig bean = run.getBean(MyConfig.class);
System.out.println(bean);
//如果@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器中有。
//保持组件单实例
User user = bean.user01();
User user1 = bean.user01();
System.out.println(user == user1);
User user01 = run.getBean("user01", User.class);
Pet tom = run.getBean("tom", Pet.class);//用户获取的pet是容器中唯一的
System.out.println("用户的宠物:"+(user01.getPet() == tom));//true
}
}
注意:springboot使用 配置类 代替 bean配置文件
@Configuration //告诉spring容器这是一个配置类,==配置文件
public class MyConfig {
//给容器添加组件,方法名为组件id,返回类型为组件类型,返回的值为组件在容器中的实例。
@Bean
public User user01(){
return new User("zhangsna",18);
}
}
最佳实战
- 配置类 组件之间无依赖关系用Lite模式加速容器启动过程,减少判断
- 因为使用Lite模式,每次从容器获取组件时不会在容器中再执行判断操作,判断组件是否存在。
- 配置类 组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式(默认)
- 容器中bean相互依赖时,full模式能保证调用的依赖组件是同一个。
- @Bean、@Component、@Controller、@Service、@Repository,它们是Spring的基本标签,在Spring Boot中并未改变它们原来的功能。
- @ComponentScan 在07、基础入门-SpringBoot-自动配置特性有用例。
- @import({User.class, DBHelper.class}) 给容器中自动创建出这两个类型的组件、默认组件的名字(beanid)就是全限定类名。
- @import放在容器中 各种组件类 上面即可。
@import({User.class, DBHelper.class})
@Configuration
public class MyConfig {
@Bean
public User user01(){
return new User("zhangsna",18);
}
@Bean("cat02")
public Pet cat(){
return new Pet("tomcat");
}
}
@SpringBootApplication(scanbasePackages = "com.rc.spring.boot")
@Slf4j
public class MainApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(MainApplication.class, args);
String[] beanNamesForType = context.getBeanNamesForType(User.class);
for (String s : beanNamesForType) {
System.out.println(s);
}
//com.rc.spring.boot.bean.User
//user01
DBHelper bean1 = context.getBean(DBHelper.class);
System.out.println(bean1);//ch.qos.logback.classic.db.DBHelper@61942c1
}
}
15、底层注解-@Conditional条件装配
- 条件装配:满足Conditional指定的条件时,才进行组件注入。
- 以前标注@Bean的都会注册到容器中
- @Conditional可以标注在类上,或方法上
举例:
用@ConditionalOnBean举例说明,user有一只猫,即存在依赖关系,故需要实现当容器中没有猫组件时,user组件也不注册到容器中。
@Configuration(proxyBeanMethods = false)
public class MyConfig {
//在容器中有tom名字的Bean时,user01的bean才会注册到容器中。否则不会注册
@ConditionalOnBean(name = "tom")
@Bean
public User user01(){
User zhangsan = new User("zhangsan", 18);
zhangsan.setPet(tomcatPet());
return zhangsan;
}
public Pet tom(){
return new Pet("tomcat");
}
}
@ConditionOnBeanname="tom")标注在类上:是说只有在容器中有名字为 tom 的bean时,该类里的所有bean才会生效。否则不生效
@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(name = "tom")//有tom名字的Bean时,MyConfig类的Bean才能生效。
public class MyConfig {
@Bean
public User user01(){
User zhangsan = new User("zhangsan", 18);
zhangsan.setPet(tomcatPet());
return zhangsan;
}
@Bean("tom22")
public Pet tomcatPet(){
return new Pet("tomcat");
}
}
public static void main(String[] args) {
//1、返回我们IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
//2、查看容器里面的组件
String[] names = run.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
boolean tom = run.containsBean("tom");
System.out.println("容器中Tom组件:"+tom);//false
boolean user01 = run.containsBean("user01");
System.out.println("容器中user01组件:"+user01);//true
boolean tom22 = run.containsBean("tom22");
System.out.println("容器中tom22组件:"+tom22);//true
}
16、底层注解-@importResource导入Spring配置文件
比如,正常使用全注解开发后,bean.xml文件的内容已经不使用了,即里面的bean不会注册到容器中。
然而,有些公司以前使用bean.xml文件生成配置bean,当我们想继续复用bean.xml,不想全部改成注解的形式时,可以使用@importResource 来让bean.xml 继续生效,保证xml中的bean注册到容器中。
bean.xml
使用:
@import({User.class, DBHelper.class})
@Configuration //告诉spring容器这是一个配置类,==配置文件
@ConditionalOnMissingBean(name="tom")
@importResource("classpath:bean.xml")
public class MyConfig {
}
public static void main(String[] args) {
//1、返回我们IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
boolean haha = run.containsBean("haha");
boolean hehe = run.containsBean("hehe");
System.out.println("haha:"+haha);//true
System.out.println("hehe:"+hehe);//true
}
17、底层注解-@ConfigurationProperties配置绑定
17.1
只有在容器中的组件,才能拥有springboot 提供的强大功能,即容器提供的强大功能,即才能使用容器里的使用组件。
如何使用Java读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用
传统方法:
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();//得到配置文件的名字
while(enum1.hasMoreElements()) {
String strKey = (String) enum1.nextElement();
String strValue = pps.getProperty(strKey);
System.out.println(strKey + "=" + strValue);
//封装到JavaBean。
}
}
}
17.2、Spring Boot 一种配置绑定
@ConfigurationProperties + @Component
1、配置文件application.properties
mycar.brand=BYD
mycar.price=100000
2、使用@ConfigurationProperties(prefix="mycar")
将 文件内容和 实体 绑定。注意加上@Component表示是容器中组件
@Data
@NoArgsConstructor
@AllArgsConstructor
@ConfigurationProperties(prefix = "mycar")
@Component
public class Car {
String price;
String branch;
}
3、验证
@RestController //@RestController = @Controller + @ResponseBody
public class HelloController {
@Autowired
private Car car;
@RequestMapping("/car")
public Car getCar(){
return car;
}
}
只有在容器中的组件,才会拥有SpringBoot提供的强大功能
- @EnableConfigurationProperties + @ConfigurationProperties
- 一定 在配置类上 写 @EnableConfigurationProperties(Car.class)
- 开启Car配置绑定功能
- 把这个Car这个组件自动注册到容器中
- 在实体类上 @ConfigurationProperties(prefix="mycar")
application.properties
server.port=8888
mycar.branch=bmw
mycar.price=100000
@import({User.class, DBHelper.class})
@Configuration //告诉spring容器这是一个配置类,==配置文件
@ConditionalOnMissingBean(name="tom")
@importResource("classpath:beans.xml")
@EnableConfigurationProperties(Car.class)
public class MyConfig {
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@ConfigurationProperties(prefix = "mycar")
//@Component
public class Car {
String price;
String branch;
}
18、自动配置【源码分析】-自动包规则原理
参考:03、了解自动配置原理 · 语雀



