@SpringBootApplication注解分析

首先咱们分析的就是入口类Application的启动注解@SpringBootApplication,进入源码:html

复制代码
@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 {
....
}
复制代码

发现@SpringBootApplication是一个复合注解,包括@ComponentScan,和@SpringBootConfiguration@EnableAutoConfigurationjava

  • @SpringBootConfiguration继承自@Configuration,两者功能也一致,标注当前类是配置类,并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例归入到srping容器中,而且实例名就是方法名。
  • @EnableAutoConfiguration的做用启动自动的配置,@EnableAutoConfiguration注解的意思就是Springboot根据你添加的jar包来配置你项目的默认配置,好比根据spring-boot-starter-web ,来判断你的项目是否须要添加了webmvctomcat,就会自动的帮你配置web项目中所须要的默认配置。在下面博客会具体分析这个注解,快速入门的demo实际没有用到该注解。
  • @ComponentScan,扫描当前包及其子包下被@Component@Controller@Service@Repository注解标记的类并归入到spring容器中进行管理。是之前的<context:component-scan>(之前使用在xml中使用的标签,用来扫描包配置的平行支持)。因此本demo中的User为什么会被spring容器管理。

根据上面的理解,上面的入口类Application,咱们可使用:web

package com.zhihao.miao;
import com.zhihao.miao.bean.User;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import java.util.Map;

@ComponentScan
public class Application {

    @Bean
    public Runnable createRunnable(){
        return () -> System.out.println("spring boot is running");
    }

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(Application.class,args);
        context.getBean(Runnable.class).run();
        System.out.println(context.getBean(User.class));
        Map map = (Map) context.getBean("createMap");
        int age = (int) map.get("age");
        System.out.println("age=="+age);

    }
}

使用@ComponentScan注解代替@SpringBootApplication注解,也能够正常运行程序。缘由是@SpringBootApplication中包含@ComponentScan,而且springboot会将入口类看做是一个@SpringBootConfiguration标记的配置类,因此定义在入口类Application中的Runnable也能够归入到容器管理。spring

SpringBootApplication参数详解


图片.png
  • Class<?>[] exclude() default {}:
    根据class来排除,排除特定的类加入spring容器,传入参数value类型是class类型。
  • String[] excludeName() default {}:
    根据class name来排除,排除特定的类加入spring容器,传入参数value类型是class的全类名字符串数组。
  • String[] scanBasePackages() default {}:
    指定扫描包,参数是包名的字符串数组。
  • Class<?>[] scanBasePackageClasses() default {}:
    扫描特定的包,参数相似是Class类型数组。

看一个demo学会使用这些参数配置
在包下com.zhihao.miao.springboot定义一个启动应用类(加上@SpringBootApplication注解)数组

package com.zhihao.miao.springboot;


import com.zhihao.miao.beans.Cat;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        ConfigurableApplicationContext context =SpringApplication.run(Application.class,args);
        Cat cat = context.getBean(Cat.class);
        System.out.println(cat);
    }
}

在com.zhihao.miao.beans包下定义一个实体类,而且想将其归入到spring容器中,tomcat

public class Cat {
}
package com.zhihao.miao.beans;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfig {

    @Bean
    public Cat cat(){
        return new Cat();
    }

}

启动启动类,打印结果以下:springboot


 

说明Cat类并无归入到spring容器中,这个结果也如咱们所想,由于@SpringBootApplication只会扫描@SpringBootApplication注解标记类包下及其子包的类(特定注解标记,好比说@Controller,@Service,@Component,@Configuration和@Bean注解等等)归入到spring容器,很显然MyConfig不在@SpringBootApplication注解标记类相同包下及其子包的类,因此须要咱们去配置一下扫包路径。mvc

修改启动类,@SpringBootApplication(scanBasePackages = "com.zhihao.miao"),指定扫描路径:spring-boot

package com.zhihao.miao.springboot;

import com.zhihao.miao.beans.Cat;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication(scanBasePackages = "com.zhihao.miao")
public class Application {

    public static void main(String[] args) {
        ConfigurableApplicationContext context =SpringApplication.run(Application.class,args);
        Cat cat = context.getBean(Cat.class);
        System.out.println(cat);
    }
}

启动并打印:spa


 

固然使用@SpringBootApplication(scanBasePackageClasses = MyConfig.class),指定scanBasePackageClasses参数的value值是你须要扫描的类也能够,结果同样,不过若是多个配置类不在当前包及其子包下,则须要指定多个。

再看一个列子,
在上面的列子的相同包下(com.zhihao.miao.springboot)配置了People,并将其归入到spring容器中(@Component),咱们知道@SpringBootApplication注解会扫描当前包及其子包,因此People类会归入到spring容器中去,咱们须要将其排除在spring容器中,如何操做?
可使用@SpringBootApplication的另外二个参数(exclude或excludeName)

package com.zhihao.miao.springboot;

import org.springframework.stereotype.Component;

@Component
public class People {
}

启动类,

package com.zhihao.miao.springboot;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        ConfigurableApplicationContext context =SpringApplication.run(Application.class,args);
        People people = context.getBean(People.class);
        System.out.println(people);
    }
}

启动并打印结果:


 

而后修改@SpringBootApplication配置,

package com.zhihao.miao.springboot;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication(exclude = People.class)
public class Application {

    public static void main(String[] args) {
        ConfigurableApplicationContext context =SpringApplication.run(Application.class,args);
        People people = context.getBean(People.class);
        System.out.println(people);
    }
}

很明显启动报错。使用@excludeName注解也能够。以下,
@SpringBootApplication(excludeName = {"com.zhihao.miao.springboot.People"})

参考文档:
Springboot1.5.4官方文档

原文地址:https://www.cnblogs.com/duanxz/p/3756364.html

相关文章
相关标签/搜索