1. 程式人生 > 實用技巧 >Java必知必會-SpringBoot02

Java必知必會-SpringBoot02

目錄

五、Docker

1、簡介

Docker

是一個開源的應用容器引擎;是一個輕量級容器技術;

Docker支援將軟體編譯成一個映象;然後在映象中各種軟體做好配置,將映象釋出出去,其他使用者可以直接使用這個映象;

執行中的這個映象稱為容器,容器啟動是非常快速的。

2、核心概念

docker主機(Host):安裝了Docker程式的機器(Docker直接安裝在作業系統之上);

docker客戶端(Client):連線docker主機進行操作;

docker倉庫(Registry):用來儲存各種打包好的軟體映象;

docker映象(Images):軟體打包好的映象;放在docker倉庫中;

docker容器(Container):映象啟動後的例項稱為一個容器;容器是獨立執行的一個或一組應用

使用Docker的步驟:

1)、安裝Docker

2)、去Docker倉庫找到這個軟體對應的映象;

3)、使用Docker執行這個映象,這個映象就會生成一個Docker容器;

4)、對容器的啟動停止就是對軟體的啟動停止;

3、安裝Docker

1)、安裝linux虛擬機器

​ 1)、VMWare、VirtualBox(安裝);

​ 2)、匯入虛擬機器檔案centos7-atguigu.ova;

​ 3)、雙擊啟動linux虛擬機器;使用 root/ 123456登陸

​ 4)、使用客戶端連線linux伺服器進行命令操作;

​ 5)、設定虛擬機器網路;

​ 橋接網路=選好網絡卡==接入網線;

​ 6)、設定好網路以後使用命令重啟虛擬機器的網路

service network restart

​ 7)、檢視linux的ip地址

ip addr

​ 8)、使用客戶端連線linux;

2)、在linux虛擬機器上安裝docker

步驟:(Centos7版)

1、檢查核心版本,必須是3.10及以上
uname -r
2、安裝docker
yum install docker
3、輸入y確認安裝
4、啟動docker
[root@localhost ~]# systemctl start docker
[root@localhost ~]# docker -v
Docker version 1.12.6, build 3e8e77d/1.12.6
5、開機啟動docker
[root@localhost ~]# systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
6、停止docker
systemctl stop docker

4、Docker常用命令&操作

1)、映象操作

操作 命令 說明
檢索 docker search 關鍵字 eg:docker search redis 我們經常去docker hub上檢索映象的詳細資訊,如映象的TAG。
拉取 docker pull 映象名:tag :tag是可選的,tag表示標籤,多為軟體的版本,預設是latest
列表 docker images 檢視所有本地映象
刪除 docker rmi image-id 刪除指定的本地映象

https://hub.docker.com/

2)、容器操作

軟體映象(QQ安裝程式)----執行映象----產生一個容器(正在執行的軟體,執行的QQ);

步驟:

1、搜尋映象
[root@localhost ~]# docker search tomcat
2、拉取映象
[root@localhost ~]# docker pull tomcat
3、根據映象啟動容器
docker run --name mytomcat -d tomcat:latest
4、docker ps   檢視執行中的容器
5、 停止執行中的容器
docker stop  容器的id
6、檢視所有的容器
docker ps -a
7、啟動容器
docker start 容器id
8、刪除一個容器
 docker rm 容器id
9、啟動一個做了埠對映的tomcat
[root@localhost ~]# docker run -d -p 8888:8080 tomcat
-d:後臺執行
-p: 將主機的埠對映到容器的一個埠    主機埠:容器內部的埠

10、為了演示簡單關閉了linux的防火牆
service firewalld status ;檢視防火牆狀態
service firewalld stop:關閉防火牆
11、檢視容器的日誌
docker logs container-name/container-id

更多命令參看
https://docs.docker.com/engine/reference/commandline/docker/
可以參考每一個映象的文件

3)、安裝MySQL示例

docker pull mysql

錯誤的啟動

[root@localhost ~]# docker run --name mysql01 -d mysql
42f09819908bb72dd99ae19e792e0a5d03c48638421fa64cce5f8ba0f40f5846

mysql退出了
[root@localhost ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                           PORTS               NAMES
42f09819908b        mysql               "docker-entrypoint.sh"   34 seconds ago      Exited (1) 33 seconds ago                            mysql01
538bde63e500        tomcat              "catalina.sh run"        About an hour ago   Exited (143) About an hour ago                       compassionate_
goldstine
c4f1ac60b3fc        tomcat              "catalina.sh run"        About an hour ago   Exited (143) About an hour ago                       lonely_fermi
81ec743a5271        tomcat              "catalina.sh run"        About an hour ago   Exited (143) About an hour ago                       sick_ramanujan


//錯誤日誌
[root@localhost ~]# docker logs 42f09819908b
error: database is uninitialized and password option is not specified 
  You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD;這個三個引數必須指定一個

正確的啟動

[root@localhost ~]# docker run --name mysql01 -e MYSQL_ROOT_PASSWORD=123456 -d mysql
b874c56bec49fb43024b3805ab51e9097da779f2f572c22c695305dedd684c5f
[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
b874c56bec49        mysql               "docker-entrypoint.sh"   4 seconds ago       Up 3 seconds        3306/tcp            mysql01

做了埠對映

[root@localhost ~]# docker run -p 3306:3306 --name mysql02 -e MYSQL_ROOT_PASSWORD=123456 -d mysql
ad10e4bc5c6a0f61cbad43898de71d366117d120e39db651844c0e73863b9434
[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
ad10e4bc5c6a        mysql               "docker-entrypoint.sh"   4 seconds ago       Up 2 seconds        0.0.0.0:3306->3306/tcp   mysql02

幾個其他的高階操作

docker run --name mysql03 -v /conf/mysql:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
把主機的/conf/mysql資料夾掛載到 mysqldocker容器的/etc/mysql/conf.d資料夾裡面
改mysql的配置檔案就只需要把mysql配置檔案放在自定義的資料夾下(/conf/mysql)

docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
指定mysql的一些配置引數

六、SpringBoot與資料訪問

1、JDBC

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://192.168.15.22:3306/jdbc
    driver-class-name: com.mysql.jdbc.Driver

效果:

​ 預設是用org.apache.tomcat.jdbc.pool.DataSource作為資料來源;

​ 資料來源的相關配置都在DataSourceProperties裡面;

自動配置原理:

org.springframework.boot.autoconfigure.jdbc:

1、參考DataSourceConfiguration,根據配置建立資料來源,預設使用Tomcat連線池;可以使用spring.datasource.type指定自定義的資料來源型別;

2、SpringBoot預設可以支援;

org.apache.tomcat.jdbc.pool.DataSource、HikariDataSource(SpringBoot推薦)、BasicDataSource、Druid

3、自定義資料來源型別

/**
 * Generic DataSource configuration.
 */
@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type")
static class Generic {

   @Bean
   public DataSource dataSource(DataSourceProperties properties) {
       //使用DataSourceBuilder建立資料來源,利用反射建立響應type的資料來源,並且繫結相關屬性
      return properties.initializeDataSourceBuilder().build();
   }

}

4、DataSourceInitializer:ApplicationListener

​ 作用:

​ 1)、runSchemaScripts();執行建表語句;

​ 2)、runDataScripts();執行插入資料的sql語句;

預設只需要將檔案命名為:

# schema-*.sql、data-*.sql
# 預設規則:schema.sql,schema-all.sql;
# 可以使用一下配置指定sql指令碼檔案位置
spring:
  datasource:
	schema:
      - classpath:sql/xxx.sql
      

5、操作資料庫:自動配置了JdbcTemplate操作資料庫

2、整合Druid資料來源

//匯入druid資料來源
@Configuration
public class DruidConfig {
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druid(){
       return  new DruidDataSource();
    }

    //配置Druid的監控
    //1、配置一個管理後臺的Servlet
    @Bean
    public ServletRegistrationBean statViewServlet(){  
        // url為: localhost:8080/druid  即可登入到druid後臺介面
        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        Map<String,String> initParams = new HashMap<>();
        initParams.put("loginUsername","admin");
        initParams.put("loginPassword","123456");
        initParams.put("allow","");//預設就是允許所有訪問
        initParams.put("deny","192.168.15.21");
        bean.setInitParameters(initParams);
        return bean;
    }

    //2、配置一個web監控的filter
    @Bean
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());
        Map<String,String> initParams = new HashMap<>();
        initParams.put("exclusions","*.js,*.css,/druid/*"); // 設定不過濾的頁面
        bean.setInitParameters(initParams);
        bean.setUrlPatterns(Arrays.asList("/*")); // 監控除了exclusions 的所有頁面
        return  bean;
    }
}

3、整合MyBatis

		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.3.1</version>
		</dependency>

步驟:

​ 1)、配置資料來源相關屬性(見上一節Druid)

​ 2)、給資料庫建表

​ 3)、建立JavaBean

4)、註解版

//指定這是一個操作資料庫的mapper
@Mapper
public interface DepartmentMapper {

    @Select("select * from department where id=#{id}")
    public Department getDeptById(Integer id);

    @Delete("delete from department where id=#{id}")
    public int deleteDeptById(Integer id);

    @Options(useGeneratedKeys = true,keyProperty = "id")  // useGeneratedKeys自動生成id,keyProperty指定主鍵
    @Insert("insert into department(departmentName) values(#{departmentName})")
    public int insertDept(Department department);

    @Update("update department set departmentName=#{departmentName} where id=#{id}")
    public int updateDept(Department department);
}

問題:

自定義MyBatis的配置規則;給容器中新增一個ConfigurationCustomizer;

@org.springframework.context.annotation.Configuration
public class MyBatisConfig {

    @Bean
    public ConfigurationCustomizer configurationCustomizer(){
        return new ConfigurationCustomizer(){	
            @Override
            public void customize(Configuration configuration) {
                configuration.setMapUnderscoreToCamelCase(true); // 自定義定製其,開啟駝峰命名規則
            }
        };
    }
}
  • @MapperScan()
// 使用MapperScan批量掃描所有的Mapper介面;
@MapperScan(value = "com.atguigu.springboot.mapper")   // 掃描所有Mapper層檔案,相當於該包下的所有Mapper檔案加上@Mapper註解
@SpringBootApplication
public class SpringBoot06DataMybatisApplication {
	public static void main(String[] args) {
		SpringApplication.run(SpringBoot06DataMybatisApplication.class, args);
	}
}

5)、配置檔案版

mybatis:
  config-location: classpath:mybatis/mybatis-config.xml # 指定mybatis全域性配置檔案的位置
  mapper-locations: classpath:mybatis/mapper/*.xml  # 指定sql對映檔案的位置	
  • mybatis全域性配置檔案mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
</configuration>
  • sql對映檔案(常用)(如EmployeeMapper.xml)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.springboot.mapper.EmployeeMapper">
   <!--  public Employee getEmpById(Integer id);
         public void insertEmp(Employee employee);
   -->
    <select id="getEmpById" resultType="com.atguigu.springboot.bean.Employee">
        SELECT * FROM employee WHERE id=#{id}
    </select>
    <insert id="insertEmp">
        INSERT INTO employee(lastName,email,gender,d_id) VALUES (#{lastName},#{email},#{gender},#{dId})
    </insert>
</mapper>

4、整合SpringData JPA

1)、SpringData簡介

2)、整合SpringData JPA

JPA:ORM(Object Relational Mapping);即 JPA是基於ORM物件關係對映的

1)、編寫一個實體類(bean)和資料表進行對映,並且配置好對映關係;

//使用JPA註解配置對映關係
@Entity //告訴JPA這是一個實體類(和資料庫中的表對映的類)
@Table(name = "tbl_user") // @Table來指定和哪個資料表對應;如果省略預設表名就是user;
public class User {

    @Id //這是一個主鍵
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增主鍵
    private Integer id;

    @Column(name = "last_name",length = 50) //這是和資料表對應的一個列
    private String lastName;
    @Column //省略表示預設列名就是屬性名
    private String email;

2)、編寫一個Dao介面來操作實體類對應的資料表(Repository)

//繼承JpaRepository來完成對資料庫的操作,引數分別為對映的Entity實體類名和主鍵型別
public interface UserRepository extends JpaRepository<User,Integer> {
}

3)、基本的配置 (參照:JpaProperties)

spring:  
 jpa:
    hibernate:
#     更新或者建立資料表結構(不存在所需要的表則會自動在資料庫中建立)
      ddl-auto: update
#    控制檯顯示SQL
    show-sql: true

七、啟動配置原理

幾個重要的事件回撥機制

配置在META-INF/spring.factories

ApplicationContextInitializer

SpringApplicationRunListener

只需要放在ioc容器中

ApplicationRunner

CommandLineRunner

啟動流程:

1、建立SpringApplication物件

// initialize(sources) 方法;
private void initialize(Object[] sources) {
    //儲存主配置類
    if (sources != null && sources.length > 0) {
        this.sources.addAll(Arrays.asList(sources));
    }
    //判斷當前是否一個web應用
    this.webEnvironment = deduceWebEnvironment();
    //從類路徑下找到META-INF/spring.factories配置的所有ApplicationContextInitializer(在autoconfigure原始碼裡);然後儲存起來
    setInitializers((Collection) getSpringFactoriesInstances(
        ApplicationContextInitializer.class));
    //從類路徑下找到META-INF/spring.factories配置的所有ApplicationListener(在autoconfigure/原始碼裡)
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    //從多個配置類中找到有main方法的主配置類
    this.mainApplicationClass = deduceMainApplicationClass();
}

2、執行run方法

public ConfigurableApplicationContext run(String... args) {
   StopWatch stopWatch = new StopWatch();
   stopWatch.start();
   ConfigurableApplicationContext context = null;
   FailureAnalyzers analyzers = null;
   configureHeadlessProperty();
    
   //獲取SpringApplicationRunListeners;從類路徑下META-INF/spring.factories
   SpringApplicationRunListeners listeners = getRunListeners(args);
    //回撥所有的獲取SpringApplicationRunListener.starting()方法
   listeners.starting();
   try {
       //封裝命令列引數
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(
            args);
      //準備環境
      ConfigurableEnvironment environment = prepareEnvironment(listeners,
            applicationArguments);
       		//建立環境完成後回撥SpringApplicationRunListener.environmentPrepared();表示環境準備完成
       
      Banner printedBanner = printBanner(environment);
       
       //建立ApplicationContext;決定建立web的ioc還是普通的ioc
      context = createApplicationContext();
       
      analyzers = new FailureAnalyzers(context);
       //準備上下文環境;將environment儲存到ioc中;而且applyInitializers();
       //applyInitializers():回撥之前儲存的所有的ApplicationContextInitializer的initialize方法
       //回撥所有的SpringApplicationRunListener的contextPrepared();
      prepareContext(context, environment, listeners, applicationArguments,
            printedBanner);
       //prepareContext執行完成以後回撥所有的SpringApplicationRunListener的contextLoaded();
       
       //s重新整理容器;ioc容器初始化(如果是web應用還會建立嵌入式的Tomcat);Spring註解版
       //掃描,建立,載入所有元件的地方;(配置類,元件,自動配置)
      refreshContext(context);
       //從ioc容器中獲取所有的ApplicationRunner和CommandLineRunner進行回撥
       //ApplicationRunner先回調,CommandLineRunner再回調
      afterRefresh(context, applicationArguments);
       //所有的SpringApplicationRunListener回撥finished方法
      listeners.finished(context, null);
      stopWatch.stop();
      if (this.logStartupInfo) {
         new StartupInfoLogger(this.mainApplicationClass)
               .logStarted(getApplicationLog(), stopWatch);
      }
       //整個SpringBoot應用啟動完成以後返回啟動的ioc容器;
      return context;
   }
   catch (Throwable ex) {
      handleRunFailure(context, listeners, analyzers, ex);
      throw new IllegalStateException(ex);
   }
}

3、事件監聽機制

配置在META-INF/spring.factories

ApplicationContextInitializer

public class HelloApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        System.out.println("ApplicationContextInitializer...initialize..."+applicationContext);
    }
}

SpringApplicationRunListener

public class HelloSpringApplicationRunListener implements SpringApplicationRunListener {

    //必須有的構造器
    public HelloSpringApplicationRunListener(SpringApplication application, String[] args){

    }

    @Override
    public void starting() {
        System.out.println("SpringApplicationRunListener...starting...");
    }

    @Override
    public void environmentPrepared(ConfigurableEnvironment environment) {
        Object o = environment.getSystemProperties().get("os.name");
        System.out.println("SpringApplicationRunListener...environmentPrepared.."+o);
    }

    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        System.out.println("SpringApplicationRunListener...contextPrepared...");
    }

    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
        System.out.println("SpringApplicationRunListener...contextLoaded...");
    }

    @Override
    public void finished(ConfigurableApplicationContext context, Throwable exception) {
        System.out.println("SpringApplicationRunListener...finished...");
    }   
}

配置(META-INF/spring.factories)

org.springframework.context.ApplicationContextInitializer=\
com.atguigu.springboot.listener.HelloApplicationContextInitializer

org.springframework.boot.SpringApplicationRunListener=\
com.atguigu.springboot.listener.HelloSpringApplicationRunListener

只需要放在ioc容器中

ApplicationRunner

@Component
public class HelloApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("ApplicationRunner...run....");
    }
}

CommandLineRunner

@Component
public class HelloCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("CommandLineRunner...run..."+ Arrays.asList(args));
    }
}

八、自定義starter

starter:

​ 1、這個場景需要使用到的依賴是什麼?

​ 2、如何編寫自動配置

@Configuration  //指定這個類是一個配置類
@ConditionalOnXXX  //在指定條件成立的情況下自動配置類生效
@AutoConfigureAfter  //指定自動配置類的順序
@Bean  //給容器中新增元件

@ConfigurationPropertie結合相關xxxProperties類來繫結相關的配置
@EnableConfigurationProperties //讓xxxProperties生效加入到容器中

自動配置類要能載入
將需要啟動就載入的自動配置類,配置在META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\

​ 3、模式:

啟動器只用來做依賴匯入;

專門來寫一個自動配置模組;

啟動器依賴自動配置;別人只需要引入啟動器(starter)

mybatis-spring-boot-starter;自定義啟動器名-spring-boot-starter

步驟:

1)、啟動器模組

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.atguigu.starter</groupId>
    <artifactId>atguigu-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--啟動器-->
    <dependencies>

        <!--引入自動配置模組-->
        <dependency>
            <groupId>com.atguigu.starter</groupId>
            <artifactId>atguigu-spring-boot-starter-autoconfigurer</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

2)、自動配置模組

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>

   <groupId>com.atguigu.starter</groupId>
   <artifactId>atguigu-spring-boot-starter-autoconfigurer</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>jar</packaging>

   <name>atguigu-spring-boot-starter-autoconfigurer</name>
   <description>Demo project for Spring Boot</description>

   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>1.5.10.RELEASE</version>
      <relativePath/> <!-- lookup parent from repository -->
   </parent>

   <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      <java.version>1.8</java.version>
   </properties>

   <dependencies>

      <!--引入spring-boot-starter;所有starter的基本配置-->
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter</artifactId>
      </dependency>

   </dependencies>



</project>

package com.atguigu.starter;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "atguigu.hello")
public class HelloProperties {  // 配置類

    private String prefix;
    private String suffix;

    public String getPrefix() {
        return prefix;
    }

    public void setPrefix(String prefix) {
        this.prefix = prefix;
    }

    public String getSuffix() {
        return suffix;
    }

    public void setSuffix(String suffix) {
        this.suffix = suffix;
    }
}

package com.atguigu.starter;

// 自定義元件,用到的屬性與配置類繫結
public class HelloService {  

    HelloProperties helloProperties;

    public HelloProperties getHelloProperties() {
        return helloProperties;
    }

    public void setHelloProperties(HelloProperties helloProperties) {
        this.helloProperties = helloProperties;
    }

    public String sayHellAtguigu(String name){
        return helloProperties.getPrefix()+"-" +name + helloProperties.getSuffix();
    }
}

package com.atguigu.starter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConditionalOnWebApplication //web應用才生效
@EnableConfigurationProperties(HelloProperties.class) 
public class HelloServiceAutoConfiguration { // 自動配置類

    @Autowired
    HelloProperties helloProperties;  
    @Bean
    public HelloService helloService(){
        HelloService service = new HelloService();
        service.setHelloProperties(helloProperties);
        return service;
    }
}