springboot学习笔记--@SpringBootApplication

目录

0.关于@SpringBootApplication的源码

1.为何将application.calss置于项目的根目录下

2.@SpringBootApplication注解的主要作用

3.application.class文件放置其他目录的配置方法


使用IDEA生成springboot项目的时候,会为我们生成一个根目录下的xxxxApilcation.class文件,然后在这个application.calss中会有一个main方法,我们只要运行这个main方法项目就可以跑起来了,那么不知道有没有人注意到这个application上面的注解@SpringBootApplication,我稍微研究了下这个注解,在这里做个记录。

写到这里呢,先抛出一连串的问题,这篇文章呢也是围绕这些问题来写的:

  • 为什么我们的  xxxAplication.class文件要放在项目的跟目录下,而且要加上@SpringBootApplication注解?
  • @SpringBootApplication注解的主要作用是什么?
  • 这个 application.calss 可不可以放到其他的目录中,要如何配置?

0.关于@SpringBootApplication的源码

先打开源码看看,这个注解的内容

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.SpringBootConfiguration;
import org.springframework.boot.context.TypeExcludeFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.annotation.AliasFor;

/**
 * Indicates a {@link Configuration configuration} class that declares one or more
 * {@link Bean @Bean} methods and also triggers {@link EnableAutoConfiguration
 * auto-configuration} and {@link ComponentScan component scanning}. This is a convenience
 * annotation that is equivalent to declaring {@code @Configuration},
 * {@code @EnableAutoConfiguration} and {@code @ComponentScan}.
 *
 * @author Phillip Webb
 * @author Stephane Nicoll
 * @since 1.2.0
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
		@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

	/**
	 * Exclude specific auto-configuration classes such that they will never be applied.
	 * @return the classes to exclude
	 */
	@AliasFor(annotation = EnableAutoConfiguration.class)
	Class[] exclude() default {};

	/**
	 * Exclude specific auto-configuration class names such that they will never be
	 * applied.
	 * @return the class names to exclude
	 * @since 1.3.0
	 */
	@AliasFor(annotation = EnableAutoConfiguration.class)
	String[] excludeName() default {};

	/**
	 * Base packages to scan for annotated components. Use {@link #scanBasePackageClasses}
	 * for a type-safe alternative to String-based package names.
	 * @return base packages to scan
	 * @since 1.3.0
	 */
	@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
	String[] scanBasePackages() default {};

	/**
	 * Type-safe alternative to {@link #scanBasePackages} for specifying the packages to
	 * scan for annotated components. The package of each class specified will be scanned.
	 * 

* Consider creating a special no-op marker class or interface in each package that * serves no purpose other than being referenced by this attribute. * @return base packages to scan * @since 1.3.0 */ @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses") Class[] scanBasePackageClasses() default {}; }

从注释里面可以看到@SpringBootApplication这个注解相当于下面三个的合体

  • @Configuration   -- 声明为配置文件
  • @EnableAutoConfiguration  -- 声明自动配置
  • @ComponentScan -- 组件扫描

springboot学习笔记--@SpringBootApplication_第1张图片

围绕着源码,我们来一一解答上面的三个问题。

1.为何将application.calss置于项目的根目录下

为application.class文件声明了@SpringBootApplication注解就包含了声明了组件扫描的注解@ComponentScan,我们打开看下组件扫描的注解

springboot学习笔记--@SpringBootApplication_第2张图片

看注释中有说明,如果我们没有定义包扫描的路径,就会自动从使用了改注解的包开始扫描起,也就是会从我们的项目根目录往下扫描,因此我们一般在跟目录之下会再放几个包 类似 dao , service , controller,config,entity等,那么这些也会被自动扫描。扫描之后就会装载到spring的容器中去。

其实将application.class加上@SpringBootApplication注解文件并且放在项目的根目录下,无论使用还是项目架构上都会方便很多,不然的话,我们还需要一一指定包扫描路径,如下

@SpringBootApplication(scanBasePackages = {"com.cjt.demo.controller","com.cjt.demo.service"})

2.@SpringBootApplication注解的主要作用

@SpringBootApplication注解的主要作用其实就是他所包含的三个注解的功能,如果不使用这个注解,那么在application.class启动类上,我们要分别加上@Configuration、@EnableAutoConfiguration、@ComponentScan这三个注解。

@ComponentScan这个是包扫描的注解,主要作用就是将所有组件在初始化的时候注入到Spring容器中,让spring进行管理,例如我们常用的@Controller @Service @Autowired等注解,如果没有被扫描加载到容器中被spring管理,那么使用这些注解都是无效的。

关于@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.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
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;

/**
 * Enable auto-configuration of the Spring Application Context, attempting to guess and
 * configure beans that you are likely to need. Auto-configuration classes are usually
 * applied based on your classpath and what beans you have defined. For example, if you
 * have {@code tomcat-embedded.jar} on your classpath you are likely to want a
 * {@link TomcatServletWebServerFactory} (unless you have defined your own
 * {@link ServletWebServerFactory} bean).
 * 

* When using {@link SpringBootApplication}, the auto-configuration of the context is * automatically enabled and adding this annotation has therefore no additional effect. *

* Auto-configuration tries to be as intelligent as possible and will back-away as you * define more of your own configuration. You can always manually {@link #exclude()} any * configuration that you never want to apply (use {@link #excludeName()} if you don't * have access to them). You can also exclude them via the * {@code spring.autoconfigure.exclude} property. Auto-configuration is always applied * after user-defined beans have been registered. *

* The package of the class that is annotated with {@code @EnableAutoConfiguration}, * usually via {@code @SpringBootApplication}, has specific significance and is often used * as a 'default'. For example, it will be used when scanning for {@code @Entity} classes. * It is generally recommended that you place {@code @EnableAutoConfiguration} (if you're * not using {@code @SpringBootApplication}) in a root package so that all sub-packages * and classes can be searched. *

* Auto-configuration classes are regular Spring {@link Configuration} beans. They are * located using the {@link SpringFactoriesLoader} mechanism (keyed against this class). * Generally auto-configuration beans are {@link Conditional @Conditional} beans (most * often using {@link ConditionalOnClass @ConditionalOnClass} and * {@link ConditionalOnMissingBean @ConditionalOnMissingBean} annotations). * * @author Phillip Webb * @author Stephane Nicoll * @see ConditionalOnBean * @see ConditionalOnMissingBean * @see ConditionalOnClass * @see AutoConfigureAfter * @see SpringBootApplication */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(AutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; /** * Exclude specific auto-configuration classes such that they will never be applied. * @return the classes to exclude */ Class[] exclude() default {}; /** * Exclude specific auto-configuration class names such that they will never be * applied. * @return the class names to exclude * @since 1.3.0 */ String[] excludeName() default {}; }

3.application.class文件放置其他目录的配置方法

搞明白的上面两个问题,其实第三个问题就非常好办了,启动文件是支持放到其他的包的,不过放到其他包之后,注解的配置要相应的进行更改

  • 如果是使用@SpringBootApplication注解,需要在注解后面补充完整指定的扫描路径

例如:

@SpringBootApplication(scanBasePackages = {"com.cjt.nbadmin.controller","com.cjt.nbadmin.service"})
  • 如果是使用三个注解的组合,注意要在@ComponentScan中补充完整指定的扫描路径

例如:

@ComponentScan(scanBasePackages = {"com.cjt.nbadmin.controller","com.cjt.nbadmin.service"})

 

 

你可能感兴趣的:(Spring,Boot学习笔记)