• springboot系列(三) 启动类中关键注解作用解析


    一、Springboot:请求入口
     
    @SpringBootApplication
    @EnableAspectJAutoProxy
    @EnableScheduling
    @EnableTransactionManagement
    public class Application {
        
        public static void main(String[] args) {
     
            SpringApplication.run(Application.class, args);
     
        }
    }

    1、@SpringBootApplication注解

    @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 {
                   ……
    }

    复合注解:包含@EnableAutoConfiguration、@ComponentScan、@SpringBootConfiguration

    a 、@EnableAutoConfiguration:也是复合注解、借助@Import将所有符合自动配置条件的bean定义加载到Spring ioc 中。帮助springboot应用将所有符合条件的@configuration配置都加载到当前spring ioc。

    @Import注解的使用。这个注解帮助我们将多个配置文件(可能是按功能分,或是按业务分)导入到单个主配置中,以避免将所有配置写在一个配置中

    b、@ComponentScan:主要作用扫描当前包及其子包下被@Component,@Controller,@Service,@Repository注解标记的类并纳入到spring容器中进行管理。是以前的<context:component-scan>(以前使用在xml中使用的标签,用来扫描包配置的平行支持)。可通过@ComponentScan 的basepackage等属性来指定扫描范围。(@SpringBootApplication(scanBasePackages = "com.ucredit")。如果不指定默认spring框架实现,从声明@ComponentScan所在的类的package进行扫描。所以springboot的启动类最好放在root package下。

    c、@SpringBootConfiguration:继承自@Configuration,二者功能也一致,标注当前类是配置类,并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到spring容器中,并且实例名就是方法名。@SpringBootConfiguration注解类相当于spring配置bean的xml文件。

    d、@Configuration

    Spring是给予IOC的,在4.0之前的版本,通常都是程序依赖上下文xml文件来管理bean,尽管有了扫描配置后相对简单,然而java配置的方式不同于xml,通过注解能够更简单。下面我们通过这两种方式比较下。

    • xml中bean的定义
    <beans>
        <bean id="course" class="demo.Course">
            <property name="module" ref="module"/>
        </bean>
        <bean id="module" class="demo.Module">
            <property name="assignment" ref="assignment"/>
        </bean>
        <bean id="assignment" class="demo.Assignment" />
    </beans>
    • 注解配置类
    @Configuration
    public class AppContext {
        @Bean
        public Course course() {
            Course course = new Course();
            course.setModule(module());
            return course;
        }
        @Bean
        public Module module() {
            Module module = new Module();
            module.setAssignment(assignment());
            return module;
        }
        @Bean
        public Assignment assignment() {
            return new Assignment();
        }
    }

    @Configuration,该注解配置在类上,告知Spring这个类是一个拥有bean定义和依赖项的配置类。@Bean注释用于定义Bean,该注解位于实例化bean并设置依赖项的方法上。方法名默认通beanId活默认名称相同,该方法返回类型是Spring注册的bean。总体来说就是告诉Spring容器加载这个配置,相对于xml,这个注解就是将*.xml配置进web.xml

    e、@Import

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Import {
     
        /**
         * {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar}
         * or regular component classes to import.
         */
        Class<?>[] value();
     
    }
    • @Import 与xml配置方式下的 作用一样。支持导入的类型有: 
      一个或多个拥有 @Configuration 注解的配置类
    • ImportSelector 接口的实现类
    • ImportBeanDefinitionRegistrar 的实现类

     1)、如果Import注解中Class为ImportSelector子类,通过invokeAwareMethods(selector)设置aware值,如果类型为  DeferredImportSelector则添加到deferredImportSelectors集合中,待前面的parser.parse(configCandidates)
     方法中processDeferredImportSelectors()处理;如果不是,则执行selectImports方法,将获取到的结果递归调用  processImports,解析selectImports得到的结果

     2)、如果Import注解中Class为ImportBeanDefinitionRegistrar子类,则添加到importBeanDefinitionRegistrars中,注 意该部分的数据在执行完parser.parse(configCandidates)后调用this.reader.loadBeanDefinitions(configClasses)解 析,否则执行配置信息的解析操作。

    public interface Car {
     
         public void print();
    }
    @Component
    public class Toyota implements Car {
     
        @Override
        public void print() {
            // TODO Auto-generated method stub
             System.out.println("I am Toyota");
        }
     
    }
     
    @Component
    public class Volkswagen implements Car {
     
        @Override
        public void print() {
            // TODO Auto-generated method stub
            System.out.println("I am Volkswagen");
        }
     
    }
     
    @Configuration
    public class JavaConfigA {
        
        @Bean(name="volkswagen")
        public Car getVolkswagen(){
            return new Volkswagen();
        }
    }
     
    @Configuration
    public class JavaConfigB {
        @Bean(name="toyota")
        public Car getToyota(){
            return new Toyota();
        }
    }
     
    @Configuration
    @Import({JavaConfigA.class,JavaConfigB.class})
    public class ParentConfig {
        //Any other bean definitions
    }
    public class ContextLoader {
     
          public static void main (String args[]){
                AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ParentConfig.class);
                Car car = (Toyota)context.getBean("toyota");
                car.print();
                car = (Volkswagen)context.getBean("volkswagen");
                car.print();
                context.close();
            }
    }
     
     
  • 相关阅读:
    1001. 害死人不偿命的(3n+1)猜想 (15)
    单链表排序
    简单插入排序
    简单选择排序
    C语言-随机数
    二分查找(折半查找)
    顺序查找-顺序查找-带哨兵查找
    队列-链表实现
    循环队列_数组实现
    队列-顺序存储-简单实现
  • 原文地址:https://www.cnblogs.com/keepruning/p/9289995.html
Copyright © 2020-2023  润新知