SpringBoot核心

基本配置

入口类和@SpringBootApplication

SpringBoot通常有一个名为*Application的入口类,入口类里面有一个main方法,这个main方法其实就是一个标准的Java应用的入口方法。在main方法中使用SpringApplication.run(Application.class, args),启动SpringBoot应用项目。

@SpringBootApplication
public class Application {
	public static void main(String[] args) {
		ApplicationContext applicationContext=SpringApplication.run(Application.class, args);
                SpringContextUtil.setApplicationContext(applicationContext);
	}
}

@SpringBootApplication是Spring Boot的核心注解,它是一个组合注解,源码如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Configuration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {

	Class<?>[] exclude() default {};

	String[] excludeName() default {};

	@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
	String[] scanBasePackages() default {};
	
	@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
	Class<?>[] scanBasePackageClasses() default {};
}

@SpringBootApplication注解主要组合了@Configuration、@EnableAutoConfiguration、@ComponentScan;若不使用@SpringBootApplication注解,则可以在入口类上直接使用@Configuration、@EnableAutoConfiguration、@ComponentScan。

其中,@EnableAutoConfiguration让Spring Boot根据类路径中的jar包依赖为当前项目进行自动配置。

例如,添加了spring-boot-starter-web依赖,会自动添加Tomcat和SpringMVC的依赖,那么SpringBoot会对Tomcat和SpringMVC进行自动配置。

又如,添加了spring-boot-starter-data-jpa依赖,SpringBoot会自动进行JPA相关的配置。

Spring Boot会自动扫描@SpringBootApplication所在类的同级包以及下级包里的Bean(若为JPA项目还可以扫描标注@Entity的实体类)。建议入口类放置的位置在groupId+arctifactId组合的包名下。

关闭特定的自动配置

关闭特定的自动配置应该使用@SpringBootApplication注解的exclude参数,例如:

@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})

定制Banner

1、修改Banner

在Spring Boto启动的时候会有一个默认启动图案,如图:

(2)在src/main/resources下新建一个banner.txt。

(3)通过http://patorjk.com/software/taag网站生成字符,将网站生成的字符复制到banner.txt中。

(4)这时再启动程序,图案变成:

 2、关闭Banner

将main里面的内容修改为:

public static void main(String[] args) {
  SpringApplication app=new SpringApplication(Application.class);
  app.setBannerMode(Banner.Mode.OFF);
  app.run(args);
}

SpringBoot的配置文件

        SpringBoot使用一个全局的配置文件application.properties或application.yml,放置在src/main/resources目录下或者类路径的/config下。

        SpringBoot不仅支持常规的properties配置文件,还支持yaml语言的配置文件。yaml是以数据为中心的语言,在配置数据的时候具有面向对象的特征。

        SpringBoot的全局配置文件的作用是对一些默认配置的配置值进行修改。

1、简单示例

将Tomcat的默认端口号8080修改为9090,并将默认的访问路径“/”修改为“/helloboot”。

可以在application.properties中添加:

server.port=9090
server.context-path=/helloboot

或在application.yml中添加:

server:
  port: 9090
  contextPath: /helloboot

从上面的配置可以看出,在SpringBoot中,context-path、contextPath形式是通用的。

starter pom

       Spring Boot为我们提供了简化企业级开发绝大多数场景的starter pom,只要使用了应用场景所需要的starter pom,相关的技术配置将会消除,就可以得到Spring Boot为我们提供的自动配置的Bean。

                                                                                 常用的几个starter pom 

                                                                                   (官方starter pom)

名称描述
spring-boot-starterSpring Boot核心starter,包含自动配置、日志、yaml配置文件的支持
spring-boot-actuator准生产特性,用来监控和管理应用
spring-boot-starter-aop使用spring-aop和AspectJ支持面向切面编程
spring-boot-starter-data-jpa对JPA的支持,包含spring-data-jpa、spring-orm和Hibernate
spring-boot-starter-data-mongodb通过spring-data-mongodb,对MongoDB进行支持
spring-boot-starter-jdbc对JDBC数据库的支持
spring-boot-starter-redis对键值对内存数据库Redis的支持,包含spring-redis
spring-boot-starter-security对spring-security的支持
spring-boot-starter-web对Web项目开发的支持,包含Tomcat和spring-webmvc
spring-boot-starter-TomcatSpring Boot默认的Servlet容器Tomcat
spring-boot-starter-log4j支持使用Log4J日志框架
spring-boot-starter-websocket对WebSocket开发的支持

 

使用xml配置

Spring Boot提倡零配置,即无xml配置,但是在实际项目中,可能有一些特殊要求你必须使用xml配置,这时我们可以通过Spring提供的@ImportResource来加载xml配置。例如:

@ImportResource({"classpath: some-context.xml", "classpath: another-context.xml"})

外部配置

Spring Boot允许使用properties文件、yaml文件或者命令行参数作为外部配置。

命令行参数配置

Spring Boot可以是基于jar包运行的,打成jar包的程序可以直接通过下面命令运行:

java -jar xx.jar

可以通过以下命令修改Tomcat端口号:

java -jar xx.jar --server.port=9090

常规属性配置

在常规Spring环境下,注入properties文件里的值的方式——通过@PropertySource指明properties文件的位置,然后通过@Value注入值。

在Spring Boot里,我们只需在application.properties定义属性,直接使用@Value注入即可。

(1)application.properties增加属性:

server:
  servlet:
    context-path : /hellobook
  port : 8080
#添加属性
book:
  author: xiaoding
  name: zhuxian

(2)修改入口类

package com.example.SpringBootDemo1;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@SpringBootApplication
public class SpringBootDemo1Application {
	
	@Value("${book.author}")
	private String bookAuthor;
	
	@Value("${book.name}")
	private String bookName;
	
	@RequestMapping("/")
	String index() {
		return "作者:"+bookAuthor+"  书名:"+bookName;
	}

	public static void main(String[] args) {
		SpringApplication.run(SpringBootDemo1Application.class, args);
	    
	}

}

(3)运行,访问:http://localhost:8080/hellobook/

类型安全的配置(基于properties)

使用@Value注入每个配置在实际项目中会显得格外麻烦,因为配置通常会是许多个,使用上面的方式要使用@Value注入很多次。

Spring Boot提供了基于类型安全的配置方式,通过@ConfigurationProperties将Properties属性和一个Bean及其属性关联,从而实现类型安全的配置。

(1)新建Spring Boot项目

(2)添加配置,即在application.yml上添加:

server:
  servlet:
    context-path : /helloAuthor
  port : 8080
#添加属性
author:
  name: xiaoding
  age: 32

也可以新建一个properties或者yml文件,这就需要在@ConfigurationProperties的属性locations里指定properties的位置,且需要在入口类上配置。

(3)类型安全的Bean,代码如下:

package com.example.entity;

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

@Component
@ConfigurationProperties(prefix="author")
public class AuthorSettings {
	private String name;	
	private Long age;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Long getAge() {
		return age;
	}
	public void setAge(Long age) {
		this.age = age;
	}
}

代码解释

  通过@ConfigurationProperties加载properties或yml文件内的配置,通过prefix属性指定properties的配置的前缀,通过locations指定properties文件的位置,但新版本中废除了location属性,故只写前缀,默认读取application.yml中数据。

(4)检验代码

package com.example.SpringBootDemo1;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.entity.AuthorSettings;

@RestController
@SpringBootApplication
//指定实体类所在的包,如果在同一个包下,就不需要写了
@ComponentScan(basePackages= {"com.example.entity"})
public class SpringBootDemo1Application {
	
	@Autowired
	private AuthorSettings aSettings;
	
	@RequestMapping("/")
	public String home() {
		return "姓名: "+aSettings.getName()+"  年龄: "+aSettings.getAge();
	}
	public static void main(String[] args) {
		SpringApplication.run(SpringBootDemo1Application.class, args);
	}
}

(5)运行,访问:http://localhost:8080/helloAuthor/

日志配置

       Spring Boot支持Java Util Logging、Log4J、Log4J2和Logback作为日志框架,无论使用哪种日志框架,Spring Boot已为当前使用日志框架的控制台输出及文件输出做好了配置。

默认情况下,Spring Boot使用Logback作为日志框架。

配置日志级别:

logging.file=D:/mylog/log.log

配置日志文件,格式为logging.level.包名=级别:

logging.level.org.springframework.web= DEBUG

Profile配置

Profile是Spring用来针对不同的环境对不同的配置提供支持的,全局Profile配置使用application-{profile}.properties(如application-prod.properties)。

通过在application.properties中设置spring.profiles.active=prod来指定活动的Profile。

假如分为生产(prod)和开发(dev)环境,生产环境下端口号为80,开发环境下端口为8888.

(1)新建Spring Boot项目

(2)生产和开发环境下的配置文件如下:

application-prod.properties:

server-port=80

application-dev.properties:

server-port=8888

 项目目录结构如图:

(3)运行

application.properties增加:

spring.profiles.active=dev

启动程序结果为:

修改application.properties:

spring.profiles.active=prod

运行结果变为:

SpringBoot运行原理

Spring4.x提供了基于条件来配置Bean的能力,Spring Boot的实现也是基于这一原理的。

Spring Boot关于自动配置的源码在spring-boot-autoconfugure-1.3.0.x.jar内,主要包含了如图所示的配置。

若想知道Spring Boot为我们做了哪些自动配置,可以查看这里的源码。

可以通过下面三种方式查看当前项目中已启用和未启用的自动配置的报告。

(1)运行jar时增加--debug参数:

(2)在application.yml中设置属性:

(3)在STS中设置,Run->Run Configurations...,如图所示。

此时启动,可在控制台输出。已启用的自动配置为:

 未启用的自动配置为:

运作原理

关于Spring Boot的运作原理,回归到@SpringBootApplication注解上来,这个注解是一个组合注解,它的核心功能是由@EnableAutoConfiguration注解提供的。 

@EnableAutoConfiguration注解的源码:

package org.springframework.boot.autoconfigure;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.support.SpringFactoriesLoader;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

	Class<?>[] exclude() default {};

	String[] excludeName() default {};

}

这里的关键功能是@Import注解导入的配置功能,EnableAutoConfigurationImportSelector使用SpringFactoriesLoader.loadFactoryNames方法来扫描具有META-INF/spring.factories文件的jar包,而我们的spring-boot-autoconfigure-1.3.0.x.jar里就有一个spring.factories文件,此文件中声明了有哪些自动配置,如图所示。

核心注解

打开上面任意一个AutoConfiguration文件,一般都有下面的条件注解,在spring-boot-autoconfigure-1.3.0.x.jar的org.springframework.boot.autoconfigure.condition包下,条件注解如下。

@ConditionalOnBean:当容器里有指定的Bean的条件下。

@ConditionalOnClass:当类路径下有指定的类的条件下。

@ConditionalOnExpression:基于SpEL表达式作为判断条件。

@ConditionalOnJava:基于JVM版本作为判断条件。

@ConditionalOnJndi:在JNDI存在的条件下查找指定的位置。

@ConditionalOnMissingBean:当容器里没有指定Bean的情况下。

@ConditionalOnMissingClass:当类路径下没有指定的类的条件下。

@ConditionalOnNotWebApplication:当前项目不是Web项目的条件下。

@ConditionaOnProperty:指定的属性是否具有指定的值。

@ConditionalOnResource:类路径是否有指定的值。

@ConditionalOnSingleCandidate:当指定Bean在容器中只有一个,或者虽然有多个但是指定首选的Bean。

@ConditionalOnWebApplication:当前项目是Web项目的条件下。

这些注解都是组合了@Conditional元注解,只是使用了不同的条件(Condition)。

下面简单分析一下@ConditionalOnWebApplication注解。

package org.springframework.boot.autoconfigure.condition;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.context.annotation.Conditional;

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnWebApplicationCondition.class)
public @interface ConditionalOnWebApplication {
}

 从源码可以看出,此注解使用的条件时OnWebApplicationCondition,下面我们看看这个条件是如何构造的:

package org.springframework.boot.autoconfigure.condition;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.StandardServletEnvironment;

@Order(Ordered.HIGHEST_PRECEDENCE + 20)
class OnWebApplicationCondition extends SpringBootCondition {

	private static final String WEB_CONTEXT_CLASS = "org.springframework.web.context."
			+ "support.GenericWebApplicationContext";

	@Override
	public ConditionOutcome getMatchOutcome(ConditionContext context,
			AnnotatedTypeMetadata metadata) {
		boolean webApplicationRequired = metadata
				.isAnnotated(ConditionalOnWebApplication.class.getName());
		ConditionOutcome webApplication = isWebApplication(context, metadata);

		if (webApplicationRequired && !webApplication.isMatch()) {
			return ConditionOutcome.noMatch(webApplication.getMessage());
		}

		if (!webApplicationRequired && webApplication.isMatch()) {
			return ConditionOutcome.noMatch(webApplication.getMessage());
		}

		return ConditionOutcome.match(webApplication.getMessage());
	}

	private ConditionOutcome isWebApplication(ConditionContext context,
			AnnotatedTypeMetadata metadata) {

		if (!ClassUtils.isPresent(WEB_CONTEXT_CLASS, context.getClassLoader())) {
			return ConditionOutcome.noMatch("web application classes not found");
		}

		if (context.getBeanFactory() != null) {
			String[] scopes = context.getBeanFactory().getRegisteredScopeNames();
			if (ObjectUtils.containsElement(scopes, "session")) {
				return ConditionOutcome.match("found web application 'session' scope");
			}
		}

		if (context.getEnvironment() instanceof StandardServletEnvironment) {
			return ConditionOutcome
					.match("found web application StandardServletEnvironment");
		}

		if (context.getResourceLoader() instanceof WebApplicationContext) {
			return ConditionOutcome.match("found web application WebApplicationContext");
		}

		return ConditionOutcome.noMatch("not a web application");
	}

}

从isWebApplication方法可以看出,判断条件是:

(1)GenericWebApplicationContext是否在类路径中;

(2)容器里是否有名为session的scope;

(3)当前容器的Environment是否为StandardServletEnvironment;

(4)当前的ResourceLoader是否为WebApplicationContext(ResourceLoader是ApplicationContext的顶级接口之一);

(5)我们需要构造ConditionOutcome类的对象来帮助我们,最终通过ConditionOutCome.isMatch()方法返回布尔值来确定条件。

实例分析

在了解了Spring Boot的运作原理和主要的条件注解后,现在来分析一个简单的Spring Boot内置的自动配置功能:http的编码配置。

我们在常规项目中配置http编码的时候是在web.xml里配置一个filter,如:

<filter>
  <filter-name>encodingFilter</filter-name>
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  <init-param>
    <param-name>encoding</param-name>
    <param-value>UTF-8</param-value>
  </init-param>
  <init-param>
    <param-name>forceEncoding</param-name>
    <param-value>true</param-value>
  </init-param>
</filter>

自动配置要满足两个条件:

(1)能配置CharacterEncodingFilter这个Bean;

(2)能配置encoding和forceEncoding这两个参数。

1.配置参数

Spring Boot的自动配置也是基于类型安全的配置实现的,这里的配置类可以在application.properties中直接设置,源码如下:

package com.cn.demo.test;

import java.nio.charset.Charset;

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

@ConfigurationProperties(prefix = "spring.http.encoding")
public class HttpEncodingProperties {
	public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
	
	private Charset charset = DEFAULT_CHARSET;
	
	private boolean force = true;
	
	public Charset getCharset() {
		return this.charset;
	}
	
	public void setCharset(Charset charset) {
		this.charset = charset;
	}

	public boolean isForce() {
		return force;
	}

	public void setForce(boolean force) {
		this.force = force;
	}
}

代码解释

①在application.properties配置的时候前缀是spring.http.encoding;

②默认编码方式为UTF-8,若修改可使用spring.http.encoding.charset=编码;

③设置forceEncoding,默认为true,若修改可使用spring.http.encoding.force=false。

2.配置Bean

通过调用上述配置,并根据条件配置CharacterEncodingFilter的Bean,我们来看看源码:

package com.cn.demo.test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.CharacterEncodingFilter;

@Configuration
@EnableConfigurationProperties(HttpEncodingProperties.class)    //1
@ConditionalOnClass(CharacterEncodingFilter.class)    //2
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)    //3
public class HttpEncodingAutoConfiguration {
	@Autowired
	private HttpEncodingProperties httpEncodingProperties;
	
	@Bean    //4
	@ConditionalOnMissingBean(CharacterEncodingFilter.class)    //5
	public CharacterEncodingFilter characterEncodingFilter() {
		CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
		filter.setEncoding(this.httpEncodingProperties.getCharset().name());
		filter.setForceEncoding(this.httpEncodingProperties.isForce());
		return filter;
	}
}

代码解释

①开启属性注入,通过@EnableConfigurationProperties声明,使用@Autowired注入;

②当CharacterEncodingFilter在类路径的条件下;

③当设置spring.http.encoding=enabled的情况下,如果没有设置则默认为true,即条件符合;

④像使用Java配置的方式配置CharacterEncodingFilter这个Bean;

⑤当容器中没有这个Bean的时候新建Bean。

实战

举个例子,包含当某个类存在的时候,自动配置这个类的Bean,并可将Bean的属性在application.properties中配置。

(1)新建starter的Maven项目,如图所示。

 

 

在pom.xml中修改代码如下:

 

<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.wisely</groupId>
  <artifactId>spring-boot-starter-hello</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>spring-boot-starter-hello</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-autoconfigure</artifactId>
      <version>1.3.0.M1</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  
  <!-- 使用Spring Boot正式版时,无须下列配置 -->
  <repositories>
    <repository>
      <id>spring-milestones</id>
      <name>Spring Milestones</name>
      <url>https://repo.spring.io/milestone</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
  </repositories>
  <pluginRepositories>
    <pluginRepository>
      <id>spring-snapshots</id>
      <name>Spring Snapshots</name>
      <url>https://repo.spring.io/snapshot</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </pluginRepository>
    
    <pluginRepository>
      <id>spring-milestones</id>
      <name>Spring Milestones</name>
      <url>https://repo.spring.io/milestone</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </pluginRepository>
  </pluginRepositories>
</project>

代码解释

在此处增加Spring Boot自身的自动配置作为依赖。

(2)属性配置,代码如下:

package com.wisely.spring_boot_starter_hello;

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

@ConfigurationProperties(prefix = "hello")
public class HelloServiceProperties {
	private static final String MSG = "world";
	
	private String msg = MSG;

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}
}

代码解释

这里的配置是类型安全的属性获取。在application.properties中通过hello.msg=来设置,若不设置,默认为hello.msg=world。

(3)判断依据类,代码如下:

 

package com.wisely.spring_boot_starter_hello;

public class HelloService {
	private String msg;
	
	public String sayHello() {
		return "Hello " + msg;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}
	
}

代码解释

本例根据此类的存在与否来创建这个类的 Bean,这个类可以是第三方类库的类。

(4)自动配置类,代码如下:

package com.wisely.spring_boot_starter_hello;

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

@Configuration
@EnableConfigurationProperties(HelloServiceProperties.class)
@ConditionalOnClass(HelloService.class)
@ConditionalOnProperty(prefix = "hello", value = "enabled", matchIfMissing = true)
public class HelloServiceAutoConfiguration {
	@Autowired
	private HelloServiceProperties helloServiceProperties;
	
	@Bean
	@ConditionalOnMissingBean(HelloService.class)
	public HelloService helloService() {
		HelloService helloService = new HelloService();
		helloService.setMsg(helloServiceProperties.getMsg());
		return helloService;
	}
}

 代码解释

根据HelloServiceProperties提供的参数,并通过@ConditionalOnClass判断HelloService这个类在类路径中是否存在,且当容器中没有这个Bean的情况下自动配置这个Bean。

(5)注册配置。若想自动配置生效,需要注册自动配置类。在src/main/resources下新建META-INF/spring.factories,结构如图所示。

在spring.factories中填写如下内容注册:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.wisely.spring_boot_starter_hello.HelloServiceAutoConfiguration

若有多个自动配置,则用“,”隔开,此处“\”是为了换行后仍然能读到属性。

另外,若在此例新建的项目中无src/main/resources文件夹,右键单击项目名称,New->Source Folder,执行如图所示操作。

(6)使用starter。新建Spring Boot项目,并将我们的starter作为依赖,如图所示。

 

在pom.xml中添加spring-boot-starter-hello的依赖,代码如下:

<dependency>  
  <groupId>com.wisely</groupId>
  <artifactId>spring-boot-starter-hello</artifactId>
  <version>0.0.1-SNAPSHOT</version>
</dependency> 

我们可以在Maven的依赖里查看spring-boot-starter-hello,如图所示。

 

在开发阶段,我们引入的依赖是spring-boot-starter-hello这个项目,在starter稳定之后,我们可以将spring-boot-starter-hello通过“mvn install”安装到本地库,或者将这个jar包发布到Maven私服上。

简单的运行类代码如下:

package com.wisely.demospringboot;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.wisely.spring_boot_starter_hello.HelloService;

@RestController
@SpringBootApplication
public class DemoSpringbootApplication {

	@Autowired
	HelloService helloService;
	
	@RequestMapping("/")
	public String index() {
		return helloService.sayHello();
	}
	public static void main(String[] args) {
		SpringApplication.run(DemoSpringbootApplication.class, args);
	}

}

在代码中可以直接注入HelloService的Bean,但在项目中我们并没有配置这个Bean,这是通过自动配置完成的。

 访问http://localhost:8080/,效果如图所示:

这时,在application.properties中配置msg的内容:

此时再次访问http://localhost:8080,效果如图所示。

在application.properties中添加debug属性,查看自动配置报告:

我们新增的自动配置显示在控制台的报告中,如图所示。

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值