一、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工程,目录如下

springboot jacoco配置 springboot javaconfig_springboot jacoco配置

 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 jacoco配置 springboot javaconfig_springboot_02

(二)SpringBoot项目创建

1、第一种:https://start.spring.io

1、IDEA中新建一个项目,选择 Spring Initializr

2019版本的IDEA,直接选择Default 的URL:https://start.spring.io

springboot jacoco配置 springboot javaconfig_yml_03

 2021版本的IDEA如下

springboot jacoco配置 springboot javaconfig_springboot jacoco配置_04

然后依次输入项目\模块名, 项目保存位置,创建方式 Maven,语言Java,Group组织ID,Artifact,工程SDK版本,打包方式等

2、选择依赖版本

可选择Spring Boot的版本,以及需要用到的依赖列表

springboot jacoco配置 springboot javaconfig_application_05

3、项目\模块目录结构

springboot jacoco配置 springboot javaconfig_application_06

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初始化器地址

springboot jacoco配置 springboot javaconfig_spring_07

2021版本的IDEA如下

springboot jacoco配置 springboot javaconfig_springboot jacoco配置_04

3、第三种:Maven

1、创建普通的 Maven 项目

2、手动添加 static,templates 等目录结构

springboot jacoco配置 springboot javaconfig_springboot_09

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)

springboot jacoco配置 springboot javaconfig_yml_10

以及其依赖 jar 包

springboot jacoco配置 springboot javaconfig_spring_11



(三)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

springboot jacoco配置 springboot javaconfig_application_12

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

springboot jacoco配置 springboot javaconfig_yml_13

我们在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();
    }
}

输出如下:

springboot jacoco配置 springboot javaconfig_spring_14

 

springboot jacoco配置 springboot javaconfig_springboot_15