zoukankan      html  css  js  c++  java
  • SpringBoot的@Enable*注解的使用介绍

    @EnableAsync或@EnableConfigurationProperties背后的运行原理,是使用了@Import注解。

    @Import({User.class,Role.class,MyConfiguration.class}),@Import里面可以存放数组类型的。

    @Import用来导入一个或多个类(bean被spring容器托管)、或者配置类(配置类里面的Bean都会被spring容器托管)。

    @Enable*其实就是使用了@Import@Import其实就是导入了配置类。

    1、以如何将配置文件里面的配置注入到bean中。之前贴过了,这里再贴一下,权当自己熟悉了。

     1 package com.bie.enable;
     2 
     3 import org.springframework.boot.context.properties.ConfigurationProperties;
     4 import org.springframework.stereotype.Component;
     5 
     6 /**
     7  * 
     8  * @Description TODO
     9  * @author biehl
    10  * @Date 2018年12月31日 下午1:13:07
    11  *
    12  */
    13 @Component
    14 @ConfigurationProperties(prefix = "tomcat")
    15 public class TomcatProperties {
    16 
    17     private String hosts;
    18     private String ports;
    19     public String getHosts() {
    20         return hosts;
    21     }
    22     public void setHosts(String hosts) {
    23         this.hosts = hosts;
    24     }
    25     public String getPorts() {
    26         return ports;
    27     }
    28     public void setPorts(String ports) {
    29         this.ports = ports;
    30     }
    31     @Override
    32     public String toString() {
    33         return "TomcatProperties [hosts=" + hosts + ", ports=" + ports + "]";
    34     }
    35     
    36     
    37 }

     然后在配置文件里面进行配置:

    tomcat.hosts=192.168.11.12
    tomcat.ports=8090

    然后写一个主运行类来进行运行:

    可以看到正常运行了。运行效果就不粘贴了。

    package com.bie.enable;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.ConfigurableApplicationContext;
    
    /**
     * 
     * @Description TODO
     * @author biehl
     * @Date 2018年12月31日 下午1:15:27
     *
     */
    @SpringBootApplication
    public class TomcatApplication {
    
        public static void main(String[] args) {
            ConfigurableApplicationContext context = SpringApplication.run(TomcatApplication.class, args);
            System.out.println("------------------------------------------------------------");
            System.out.println(context.getEnvironment().getProperty("tomcat.hosts"));//从容器中获取到对象tomcat.hosts
            System.out.println(context.getEnvironment().getProperty("tomcat.ports"));//从容器中获取到对象tomcat.ports
            System.out.println("------------------------------------------------------------");
            context.close();
        }
    }

     2、ctrl键和鼠标左键点开@SpringBootApplication注解,其实可以发现,注解里面主要使用了如此注解@EnableAutoConfiguration和@ComponentScan来实现的功能的。

    注意1:@SpringBootConfiguration注解和Spring的@Configuration注解的作用是一样的。

    注意2:@EnableConfigurationProperties注解是替代@EnableAutoConfiguration,发挥作用的是@EnableConfigurationProperties注解。

     

    然后呢,你会发现,使用这两个注解和使用@SpringBootApplication注解的作用是一样的。

    package com.bie.enable;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.ConfigurableApplicationContext;
    import org.springframework.context.annotation.ComponentScan;
    
    /**
     * 
     * @Description TODO
     * @author biehl
     * @Date 2018年12月31日 下午1:15:27
     *
     */
    //@SpringBootApplication
    @EnableAutoConfiguration
    @ComponentScan
    public class TomcatApplication {
    
        public static void main(String[] args) {
            ConfigurableApplicationContext context = SpringApplication.run(TomcatApplication.class, args);
            System.out.println("------------------------------------------------------------");
            System.out.println(context.getEnvironment().getProperty("tomcat.hosts"));
            System.out.println(context.getEnvironment().getProperty("tomcat.ports"));
            System.out.println("------------------------------------------------------------");
            context.close();
        }
    }

    运行效果如下所示:

    上面说了发挥作用的@EnableConfigurationProperties,然而我测试的时候发现如下所示:

     1   .   ____          _            __ _ _
     2  /\ / ___'_ __ _ _(_)_ __  __ _    
     3 ( ( )\___ | '_ | '_| | '_ / _` |    
     4  \/  ___)| |_)| | | | | || (_| |  ) ) ) )
     5   '  |____| .__|_| |_|_| |_\__, | / / / /
     6  =========|_|==============|___/=/_/_/_/
     7  :: Spring Boot ::       (v1.5.10.RELEASE)
     8 
     9 2018-12-31 13:27:18.515  INFO 2176 --- [           main] com.bie.enable.TomcatApplication         : Starting TomcatApplication on DESKTOP-T450s with PID 2176 (E:eclipesworkguobanspring-boot-hello	argetclasses started by Aiyufei in E:eclipesworkguobanspring-boot-hello)
    10 2018-12-31 13:27:18.521  INFO 2176 --- [           main] com.bie.enable.TomcatApplication         : No active profile set, falling back to default profiles: default
    11 2018-12-31 13:27:18.600  INFO 2176 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@101df177: startup date [Mon Dec 31 13:27:18 CST 2018]; root of context hierarchy
    12 2018-12-31 13:27:18.932  WARN 2176 --- [           main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
    13 2018-12-31 13:27:19.423 ERROR 2176 --- [           main] o.s.boot.SpringApplication               : Application startup failed
    14 
    15 org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
    16     at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:137) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    17     at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537) ~[spring-context-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    18     at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    19     at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    20     at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    21     at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    22     at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    23     at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    24     at com.bie.enable.TomcatApplication.main(TomcatApplication.java:21) [classes/:na]
    25 Caused by: org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
    26     at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:189) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    27     at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:162) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    28     at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:134) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    29     ... 8 common frames omitted

    然而就百度呗,发现并没有很清晰说这个问题怎么解决的。

    https://stackoverflow.com/questions/37114076/exception-in-thread-main-org-springframework-context-applicationcontextexcepti发现了一段话,还挺有意思的。如是说,丢失注解,其实是依赖不对的问题,哈哈哈,然后看看自己的依赖。发现了问题所在。

    我一开始是使用的<artifactId>spring-boot-starter-web</artifactId>,这种web的依赖,修改为了<artifactId>spring-boot-starter</artifactId>普通项目的依赖,这样使用@EnableConfigurationProperties注解是替代@EnableAutoConfiguration运行就没有问题了。

    @EnableConfigurationProperties注解是用来启用一个特性的,这个特性就是,可以把配置文件注入到bean里面去。一般是要和@ConfigurationProperties一起使用。

     2、SpringBoot中如何启用一个异步,看看SpringBoot如何对异步进行支持的。

     1 package com.bie.enable;
     2 
     3 import java.util.concurrent.TimeUnit;
     4 
     5 import org.springframework.scheduling.annotation.Async;
     6 import org.springframework.stereotype.Component;
     7 
     8 /**
     9  * 
    10  * @Description TODO
    11  * @author biehl
    12  * @Date 2018年12月31日 下午2:08:52
    13  * 1、实现Runnable接口的类要实现run的方法
    14  */
    15 @Component //添加到容器中
    16 public class SyncRunnable implements Runnable {
    17 
    18     //@Async注解实现,异步执行
    19     @Async
    20     public void run() {
    21         try {
    22             for (int i = 0; i < 10; i++) {
    23                 System.out.println("-------------------" + i);
    24                 TimeUnit.SECONDS.sleep(1);
    25             }
    26         } catch (InterruptedException e) {
    27             e.printStackTrace();
    28         }
    29 
    30     }
    31 
    32 }

    然后写主运行类,如下所示:

     1 package com.bie.enable;
     2 
     3 import org.springframework.boot.SpringApplication;
     4 import org.springframework.boot.autoconfigure.SpringBootApplication;
     5 import org.springframework.context.ConfigurableApplicationContext;
     6 import org.springframework.scheduling.annotation.EnableAsync;
     7 
     8 /**
     9  * 
    10  * @Description TODO
    11  * @author biehl
    12  * @Date 2018年12月31日 下午2:11:52
    13  * 
    14  */
    15 @SpringBootApplication
    16 @EnableAsync //启用异步注解
    17 public class SyncApplication {
    18 
    19     public static void main(String[] args) {
    20         ConfigurableApplicationContext context = SpringApplication.run(SyncApplication.class, args);
    21         SyncRunnable bean = context.getBean(SyncRunnable.class);
    22         System.out.println(bean);
    23         bean.run();
    24         System.out.println("-----------end-----------");
    25         
    26         //关闭
    27         context.close();
    28     }
    29 }

    如果使用上面的会报错,如下所示:

     1   .   ____          _            __ _ _
     2  /\ / ___'_ __ _ _(_)_ __  __ _    
     3 ( ( )\___ | '_ | '_| | '_ / _` |    
     4  \/  ___)| |_)| | | | | || (_| |  ) ) ) )
     5   '  |____| .__|_| |_|_| |_\__, | / / / /
     6  =========|_|==============|___/=/_/_/_/
     7  :: Spring Boot ::       (v1.5.10.RELEASE)
     8 
     9 2018-12-31 14:45:34.676  INFO 7500 --- [           main] com.bie.enable.SyncApplication           : Starting SyncApplication on DESKTOP-T450s with PID 7500 (E:eclipesworkguobanspring-boot-hello	argetclasses started by Aiyufei in E:eclipesworkguobanspring-boot-hello)
    10 2018-12-31 14:45:34.682  INFO 7500 --- [           main] com.bie.enable.SyncApplication           : No active profile set, falling back to default profiles: default
    11 2018-12-31 14:45:34.991  INFO 7500 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@103f852: startup date [Mon Dec 31 14:45:34 CST 2018]; root of context hierarchy
    12 2018-12-31 14:45:38.523  INFO 7500 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
    13 2018-12-31 14:45:38.623  INFO 7500 --- [           main] com.bie.enable.SyncApplication           : Started SyncApplication in 5.1 seconds (JVM running for 5.898)
    14 Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.bie.enable.SyncRunnable' available
    15     at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:353)
    16     at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340)
    17     at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1092)
    18     at com.bie.enable.SyncApplication.main(SyncApplication.java:21)
    19 2018-12-31 14:45:38.663  INFO 7500 --- [       Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@103f852: startup date [Mon Dec 31 14:45:34 CST 2018]; root of context hierarchy
    20 2018-12-31 14:45:38.670  INFO 7500 --- [       Thread-2] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown

    百度了一下,参考链接:https://www.cnblogs.com/javJoker/p/7281688.html

    修改为了如下所示,参考链接的问题,确实也问住我了,需要深思一下吧。

    @EnableAsync //启用异步注解,一般是和@Async一起使用。来实现异步的功能。

     1 package com.bie.enable;
     2 
     3 import org.springframework.boot.SpringApplication;
     4 import org.springframework.boot.autoconfigure.SpringBootApplication;
     5 import org.springframework.context.ConfigurableApplicationContext;
     6 import org.springframework.scheduling.annotation.EnableAsync;
     7 
     8 /**
     9  * 
    10  * @Description TODO
    11  * @author biehl
    12  * @Date 2018年12月31日 下午2:11:52
    13  * 
    14  */
    15 @SpringBootApplication
    16 @EnableAsync //启用异步注解
    17 public class SyncApplication {
    18 
    19     public static void main(String[] args) {
    20         ConfigurableApplicationContext context = SpringApplication.run(SyncApplication.class, args);
    21         Runnable bean = context.getBean(Runnable.class);
    22         System.out.println(bean);
    23         bean.run();
    24         System.out.println("-----------end-----------");
    25         
    26         //关闭
    27         context.close();
    28     }
    29 }

    运行结果如下所示:

    待续......

  • 相关阅读:
    还是模块
    模块
    Django之中间件和Auth模块
    Django之form表单组件、cookie与session
    ORM表查询之F查询和Q查询以及事务
    django之单表和多表查询
    django之模板层
    Django之路由
    Django之前戏
    前端之Bootstrap框架
  • 原文地址:https://www.cnblogs.com/biehongli/p/10201880.html
Copyright © 2011-2022 走看看