一、JavaConfig
在Spring3.0之前,我们的bean一直通过XML文件来配置的,后来在Spring3.0之后为我们提供了Java的config版本。而且在Spring4.0之后推荐我们使用
JavaConfig: 是 Spring 提供的使用 java 类配置容器。 配置 Spring IOC 容器的纯 Java 方法
JavaConfig优点:
1、面向对象的配置:
由于配置被定义为JavaConfig中的类,因此可以充分使用Java中的面向对象功能。一个配置类可以继承另一个配置类,重写@Bean方法
2、减少或者消除XML配置:
JavaConfig提供了一种纯Java的方法来配置与XML配置概念相似的Spring容器。
从技术角度来说,只使用javaconfig配置类来配置容器是可行的,但是实际开发中,很多场景都是JavaConfig和XML配置共用是最方便,最理想
3、类型安全和重构好:
JavaConfig提供了一种类型安全的方法了来配置spring容器,由于Java5.0对泛型的支持,现在可以按类型而不是名称检索bean,不需要任何的强制转换或者基于字符串的查找
JavaConfig使用的主要注解
@Configuration:表示当前类作为配置文件使用(配置容器,放在类的上面;等同 xml 配置文件,可以在其中声明 bean
@ComponentScan:定义的包路径,自动扫描包路径下面的所有被@Controller、@Service、@Repository、@Component 注解标识的类,然后装配到Spring容器中 * 等同 xml 中 <context:component-scan base-package="com.mycompany.vo" />
@ImportResource:导入其他的xml配置文件;等同 xml中 <import resources="其他配置文件"/>
@PropertySource:读取properties属性配置文件 ;等同 xml文件中 <context:property-placeholder location="classpath:config.properties" />
@Bean:将对象注入到Spring容器中(类似<bean>标签,放在方法上面);不指定对象的名称,默认是方法名是 id
创建一个maven Java工程,目录如下
resources下applicationContext.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="myStudent" class="com.mycompany.vo.Student">
<property name="stuId" value="1"/>
<property name="stuName" value="zhangsan"/>
</bean>
<!-- <context:property-placeholder location="classpath:config.properties" />-->
<!-- <context:component-scan base-package="com.mycompany.vo" />-->
<!-- <import resource="classpath:beans.xml" />-->
</beans>
beans.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--声明bean对象-->
<bean id="myUser" class="com.mycompany.vo.User">
<property name="userId" value="1" />
<property name="useName" value="admin" />
</bean>
</beans>
config.properties
shop.shopId=1
shop.shopName=东东
vo对象
public class Student {
private Long stuId;
private String stuName;
public Long getStuId() {
return stuId;
}
public void setStuId(Long stuId) {
this.stuId = stuId;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
@Override
public String toString() {
return "Student{" +
"stuId=" + stuId +
", stuName='" + stuName + '\'' +
'}';
}
}
public class User {
private Long userId;
private String useName;
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getUseName() {
return useName;
}
public void setUseName(String useName) {
this.useName = useName;
}
@Override
public String toString() {
return "User{" +
"userId=" + userId +
", useName='" + useName + '\'' +
'}';
}
}
@Component("shop")
public class Shop {
@Value("${shop.shopId}")
private Long shopId;
@Value("${shop.shopName}")
private String shopName;
public Long getShopId() {
return shopId;
}
public void setShopId(Long shopId) {
this.shopId = shopId;
}
public String getShopName() {
return shopName;
}
public void setShopName(String shopName) {
this.shopName = shopName;
}
@Override
public String toString() {
return "Shop{" +
"shopId=" + shopId +
", shopName='" + shopName + '\'' +
'}';
}
}
SpringConfig.java
import com.mycompany.vo.Student;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.PropertySource;
/**
* @Configuration: 表示当前类作为配置文件使用(配置容器,放在类的上面)
* 作用:相当于 beans.xml
*/
@Configurable
/**
* @ImportResource: 导入其他的xml配置文件
* 等同 xml中 <import resources="其他配置文件"/>
*/
@ImportResource(value = {"classpath:applicationContext.xml","classpath:beans.xml"})
/**
* @PropertyResource: 读取properties属性配置文件
* 等同 xml文件中 <context:property-placeholder location="classpath:config.properties" />
*/
@PropertySource(value = "classpath:config.properties")
/**
* @ComponentScan: 定义的包路径,自动扫描包路径下面的所有被@Controller、@Service、@Repository、@Component 注解标识的类,然后装配到Spring容器中
* 等同 xml 中 <context:component-scan base-package="com.mycompany.vo" />
*/
@ComponentScan(basePackages = "com.mycompany.vo")
public class SpringConfig {
/**
* @Bean: 将对象注入到Spring容器中(类似<bean>标签,放在方法上面)
* @Bean ,不指定对象的名称,默认是方法名是 id,如:createStudent
*/
@Bean
public Student createStudent(){
Student s1 = new Student();
s1.setStuId(20L);
s1.setStuName("张三");
return s1;
}
/***
* 指定对象在容器中的名称(指定<bean>的id属性)
* @Bean 的name属性,指定对象的名称(id)
*/
@Bean(name = "lisiStudent")
public Student createStudent1(){
Student s2 = new Student();
s2.setStuId(20L);
s2.setStuName("李四");
return s2;
}
}
测试类
/**
* 使用xml作为容器配置文件
*/
@Test
public void test0(){
String config = "beans.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(config);
User myUser = (User) context.getBean("myUser");
System.out.println("容器中对象:" + myUser);
}
@Test
public void test1(){
String config = "applicationContext.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(config);
Student student = (Student) context.getBean("myStudent");
System.out.println("容器中对象:" + student);
}
/**
* 使用JavaConfig
*/
@Test
public void test2(){
//AnnotationConfigApplicationContext
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
Student student = (Student) context.getBean("createStudent");
System.out.println("使用JavaConfig创建的bean对象:" + student);
}
@Test
public void test3(){
//AnnotationConfigApplicationContext
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
Student student = (Student) context.getBean("lisiStudent");
System.out.println("使用JavaConfig创建的bean对象:" + student);
}
@Test
public void test4(){
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
User user = (User) ctx.getBean("myUser");
System.out.println("user=="+user);
}
@Test
public void test5(){
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
Shop shop = (Shop) ctx.getBean("shop");
System.out.println("shop=="+shop);
}
二、SpringBoot
(一)SpringBoot简介
众所周知 Spring 应用需要进行大量的配置,各种 XML 配置和注解配置让人眼花缭乱,且极容易出错,因此 Spring 一度被称为“配置地狱”。
为了简化 SpringMVC + Spring + MyBatis 框架
Spring Boot 是 Pivotal 团队在 Spring 的基础上提供的一套全新的开源框架,其目的是为了简化 Spring 应用的搭建和开发过程。Spring Boot 去除了大量的 XML 配置文件,简化了复杂的依赖管理。
Spring Boot 具有 Spring 一切优秀特性,Spring 能做的事,Spring Boot 都可以做,而且使用更加简单,功能更加丰富,性能更加稳定而健壮。随着近些年来微服务技术的流行,Spring Boot 也成了时下炙手可热的技术。
Spring Boot 集成了大量常用的第三方库配置,Spring Boot 应用中这些第三方库几乎可以是零配置的开箱即用(out-of-the-box),大部分的 Spring Boot 应用都只需要非常少量的配置代码(基于 Java 的配置),开发者能够更加专注于业务逻辑。
官网地址:Spring Boot
SpringBoot特点
1、Create stand-alone Spring applications
创建spring应用
2、Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)
内嵌tomcat, jetty , Undertow
3、Provide opinionated 'starter' dependencies to simplify your build configuration
提供了starter起步依赖,简化应用的配置
比如使用MyBatis框架 , 需要在Spring项目中,配置MyBatis的对象 SqlSessionFactory , Dao的代理对象
在SpringBoot项目中,在pom.xml里面, 加入一个 mybatis-spring-boot-starter依赖
4、Automatically configure Spring and 3rd party libraries whenever possible
尽可能自动配置Spring和第三方库,把spring中的,第三方库中的对象都创建好,放到容器中, 可以直接使用
5、Provide production-ready features such as metrics, health checks, and externalized configuration
提供可用于生产的特性,如度量、健康检查和外部化配置
6、Absolutely no code generation and no requirement for XML configuration
完全不需要代码生成,也不需要XML配置
(二)SpringBoot项目创建
1、第一种:https://start.spring.io
1、IDEA中新建一个项目,选择 Spring Initializr
2019版本的IDEA,直接选择Default 的URL:https://start.spring.io
2021版本的IDEA如下
然后依次输入项目\模块名, 项目保存位置,创建方式 Maven,语言Java,Group组织ID,Artifact,工程SDK版本,打包方式等
2、选择依赖版本
可选择Spring Boot的版本,以及需要用到的依赖列表
3、项目\模块目录结构
pom.xml中默认依赖如下
<dependencies>
<!-- web项目起步依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
2、第二种方式:https://start.springboot.io
2019版本的IDEA,选择Custom的URL:https://start.springboot.io
https://start.springboot.io 是国内提供的 springboot初始化器地址
2021版本的IDEA如下
3、第三种:Maven
1、创建普通的 Maven 项目
2、手动添加 static,templates 等目录结构
3、pom.xml 文件中添加依赖
<dependencies>
<!-- web项目起步依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
4、创建启动类:加入@SpringBootApplication 注解
/**
* @SpringBootApplication
* 符合注解:由
* @SpringBootConfiguration
* @EnableAutoConfiguration
* @ComponentScan
* 三个注解组成
*
* 1、@SpringBootConfiguration
* @Configuration
* public @interface SpringBootConfiguration {
* @AliasFor(
* annotation = Configuration.class
* )
* boolean proxyBeanMethods() default true;
* }
* 使用了@SpringBootConfiguration注解标注的类,可以作为配置文件使用的,可使用Bean声明对象,注入到容器
*
* 2、@EnableAutoConfiguration
* 启用自动配置, 把java对象配置好,注入到spring容器中。例如可以把mybatis的对象创建好,放入到容器中
*
* 3、@ComponentScan 扫描器,找到注解,根据注解的功能创建对象,给属性赋值等等
* 默认扫描的包: @ComponentScan所在的类所在的包和子包
*/
@SpringBootApplication
public class Springboot2HelloApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot2HelloApplication.class, args);
}
}
@SpringBootApplication符合注解:由 @SpringBootConfiguration 、@EnableAutoConfiguration 、@ComponentScan 三个注解组成
1、@SpringBootConfiguration
@SpringBootConfiguration注解标注的类,可以作为配置文件使用的,可使用Bean声明对象,注入到容器
2、@EnableAutoConfiguration 启用自动配置, 把java对象配置好,注入到spring容器中
例如可以把mybatis的对象创建好,放入到容器中
3、@ComponentScan 扫描器,找到注解,根据注解的功能创建对象,给属性赋值等等默认扫描的包
@ComponentScan所在的类所在的包和子包
启动应用,我们看控制台会内嵌一个Tomcat(默认端口8080,博主因为端口被占用,改成了8081)
以及其依赖 jar 包
(三)SpringBoot配置文件,以及多环境设置
Spring Boot 的核心配置文件用于配置 Spring Boot 程序,名字必须以 application 开始
1、配置文件名称: application
扩展名有: properties( k=v) ;yml ( k: v)
application.properties(默认采用该文件)
application.yml
yml 是一种 yaml 格式的配置文件,主要采用一定的空格、换行等格式排版进行配置。
yaml 是一种直观的能够被计算机识别的的数据序列化格式,容易被人类阅读,yaml 类似于 xml,但是语法比 xml 简洁很多,值与前面的冒号配置项必须要有一个空格, yml缀也可以使用 yaml 后缀
要么使用application.properties,要么使用 application.yml,不要同时使用(springboot默认采用是键值对的 application.properties 属性配置文件)
注意 : 当两种格式配置文件同时存在 ,在 SpringBoot2.4 开始, 使用的是 yml 配置文件
(1)application.properties 设置 端口和上下文
#设置端口号
server.port=8081
#设置访问应用上下文路径, contextpath
server.servlet.context-path=/myboot
#配置数组、List集合对象
users[0].id=1
users[0].name=zhangsan
users[0].age=18
users[1].id=2
users[1].name=lisi
users[1].age=20
注:
1、application.properties 配置文件 以 key=value 的形势出现
2、根节点 users 是 一个List 对象,其中 users 集合中 中又包含 2 个对象,每个对象有三个属性(一个 索引[0] 代表 一个对象)
(2)application.yml 设置 端口和上下文
server:
port: 8083
servlet:
context-path: /myboot2
#配置数组、List集合对象
users:
- id: 1
name: zhangsan
age: 18
- id: 2
name: lisi
age: 20
在application.yml 文件书写注意:
1、不同 “等级” 用冒号隔开
2、次等级的前面是空格(最好2个空格),不能使用制表符(tab)
3、冒号之后如果有值,那么冒号和值之间至少有一个空格,不能紧贴着
4、根节点 users 是 一个List 对象,其中 users 集合中 中又包含 2 个对象,每个对象有三个属性(一个 ‘-’ 短线 代表 一个对象)
2、多环境设置
创建多个配置文件, 名称规则: application-环境名称.properties(yml)
如:application-dev.properties( application-dev.yml );
application-test.properties( application-test.yml );
在application.properties(yml) 中设置使用的环境名 spring.profiles.active 即可
application.properties中
#设置环境
spring.profiles.active=dev
application.yml中
#设置多环境
spring:
profiles:
active: dev
3、application.properties(yml) 自定义配置
SpringBoot 的核心配置文件中,除了使用内置的配置项之外,我们还可以在自定义配 置,然后采用@Value 注解,@ConfigurationProperties 注解去读取配置的属性值
1、@Value 注解
@Value("${key}") , key 来自 application.properties(yml)
#设置端口号
server:
port: 8081
servlet:
context-path: /myBook
#设置book信息
book:
bookname: 《三十而立》
bookprice: 68.50
#访问网站
website: www.baidu.com
2、@ConfigurationProperties 注解
@ConfigurationProperties: 把配置文件的数据映射为java对象
属性:prefix 配置文件中的某些key的开头的内容
@Component 标注一个类为Spring容器的Bean(把普通pojo实例化到spring容器中,等同 xml 配置文件中的<bean id="" class=""/>)
/**
* @Component 标注一个类为Spring容器的Bean(把普通pojo实例化到spring容器中,等同 xml 配置文件中的<bean id="" class=""/>)
*/
@Component
/**
* @ConfigurationProperties: 把配置文件的数据映射为java对象
* 属性:prefix 配置文件中的某些key的开头的内容
*/
@ConfigurationProperties(prefix = "book")
public class Book {
private String bookName;
private Double bookPrice;
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public Double getBookPrice() {
return bookPrice;
}
public void setBookPrice(Double bookPrice) {
this.bookPrice = bookPrice;
}
@Override
public String toString() {
return "Book{" +
"bookName='" + bookName + '\'' +
", bookPrice=" + bookPrice +
'}';
}
}
我们在加入@ConfigurationProperties 注解时,会报如下警告
Spring Boot Configuration Annotation Processor not configured
我们在pom.xml 依赖中加入如下依赖
<!--处理ConfigurationProperties有关的元数据
加入@ConfigurationProperties注解时报错:Spring Boot Configuration Annotation Processor not configured
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
测试请求
@Controller
public class MyController {
@Value("${server.port}")
private Integer port;
@Value("${server.servlet.context-path}")
private String contextPath;
@Value("${book.bookname}")
private String bookName;
@Value("${book.bookprice}")
private Double bookPrice;
@Value("${website}")
private String webSite;
@Autowired
private Book book;
@RequestMapping("/data")
@ResponseBody
public String queryData(){
return bookName + " " + bookPrice + ",webSite=" + webSite + ", 项目的访问地址=" + contextPath + ",使用的端口=" + port;
}
@RequestMapping("/book")
@ResponseBody
public String queryInfo(){
return "book对象==" + book.toString();
}
}
输出如下: