SpringBoot的@Enable*注解的使用介绍

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

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

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

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

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

 package com.bie.enable;

 import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; /**
*
* @Description TODO
* @author biehl
* @Date 2018年12月31日 下午1:13:07
*
*/
@Component
@ConfigurationProperties(prefix = "tomcat")
public class TomcatProperties { private String hosts;
private String ports;
public String getHosts() {
return hosts;
}
public void setHosts(String hosts) {
this.hosts = hosts;
}
public String getPorts() {
return ports;
}
public void setPorts(String ports) {
this.ports = ports;
}
@Override
public String toString() {
return "TomcatProperties [hosts=" + hosts + ", ports=" + ports + "]";
} }

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

tomcat.hosts=192.168.11.12
tomcat.ports=

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

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

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注解。

SpringBoot的@Enable*注解的使用介绍

然后呢,你会发现,使用这两个注解和使用@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();
}
}

运行效果如下所示:

SpringBoot的@Enable*注解的使用介绍

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

   .   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.10.RELEASE) -- ::18.515 INFO --- [ main] com.bie.enable.TomcatApplication : Starting TomcatApplication on DESKTOP-T450s with PID (E:\eclipeswork\guoban\spring-boot-hello\target\classes started by Aiyufei in E:\eclipeswork\guoban\spring-boot-hello)
-- ::18.521 INFO --- [ main] com.bie.enable.TomcatApplication : No active profile set, falling back to default profiles: default
-- ::18.600 INFO --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@101df177: startup date [Mon Dec :: CST ]; root of context hierarchy
-- ::18.932 WARN --- [ 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.
-- ::19.423 ERROR --- [ main] o.s.boot.SpringApplication : Application startup failed 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.
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:) ~[spring-boot-1.5..RELEASE.jar:1.5..RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:) ~[spring-context-4.3..RELEASE.jar:4.3..RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:) ~[spring-boot-1.5..RELEASE.jar:1.5..RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:) [spring-boot-1.5..RELEASE.jar:1.5..RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:) [spring-boot-1.5..RELEASE.jar:1.5..RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:) [spring-boot-1.5..RELEASE.jar:1.5..RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:) [spring-boot-1.5..RELEASE.jar:1.5..RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:) [spring-boot-1.5..RELEASE.jar:1.5..RELEASE]
at com.bie.enable.TomcatApplication.main(TomcatApplication.java:) [classes/:na]
Caused by: org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:) ~[spring-boot-1.5..RELEASE.jar:1.5..RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:) ~[spring-boot-1.5..RELEASE.jar:1.5..RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:) ~[spring-boot-1.5..RELEASE.jar:1.5..RELEASE]
... common frames omitted

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

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

SpringBoot的@Enable*注解的使用介绍

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

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

SpringBoot的@Enable*注解的使用介绍

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

 package com.bie.enable;

 import java.util.concurrent.TimeUnit;

 import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component; /**
*
* @Description TODO
* @author biehl
* @Date 2018年12月31日 下午2:08:52
* 1、实现Runnable接口的类要实现run的方法
*/
@Component //添加到容器中
public class SyncRunnable implements Runnable { //@Async注解实现,异步执行
@Async
public void run() {
try {
for (int i = ; i < ; i++) {
System.out.println("-------------------" + i);
TimeUnit.SECONDS.sleep();
}
} catch (InterruptedException e) {
e.printStackTrace();
} } }

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

 package com.bie.enable;

 import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.EnableAsync; /**
*
* @Description TODO
* @author biehl
* @Date 2018年12月31日 下午2:11:52
*
*/
@SpringBootApplication
@EnableAsync //启用异步注解
public class SyncApplication { public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SyncApplication.class, args);
SyncRunnable bean = context.getBean(SyncRunnable.class);
System.out.println(bean);
bean.run();
System.out.println("-----------end-----------"); //关闭
context.close();
}
}

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

   .   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.10.RELEASE) -- ::34.676 INFO --- [ main] com.bie.enable.SyncApplication : Starting SyncApplication on DESKTOP-T450s with PID (E:\eclipeswork\guoban\spring-boot-hello\target\classes started by Aiyufei in E:\eclipeswork\guoban\spring-boot-hello)
-- ::34.682 INFO --- [ main] com.bie.enable.SyncApplication : No active profile set, falling back to default profiles: default
-- ::34.991 INFO --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@103f852: startup date [Mon Dec :: CST ]; root of context hierarchy
-- ::38.523 INFO --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
-- ::38.623 INFO --- [ main] com.bie.enable.SyncApplication : Started SyncApplication in 5.1 seconds (JVM running for 5.898)
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.bie.enable.SyncRunnable' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:)
at com.bie.enable.SyncApplication.main(SyncApplication.java:)
-- ::38.663 INFO --- [ Thread-] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@103f852: startup date [Mon Dec :: CST ]; root of context hierarchy
-- ::38.670 INFO --- [ Thread-] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown

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

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

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

 package com.bie.enable;

 import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.EnableAsync; /**
*
* @Description TODO
* @author biehl
* @Date 2018年12月31日 下午2:11:52
*
*/
@SpringBootApplication
@EnableAsync //启用异步注解
public class SyncApplication { public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SyncApplication.class, args);
Runnable bean = context.getBean(Runnable.class);
System.out.println(bean);
bean.run();
System.out.println("-----------end-----------"); //关闭
context.close();
}
}

运行结果如下所示:

SpringBoot的@Enable*注解的使用介绍

待续......

上一篇:python 实现斐波那契数列


下一篇:倍增\ tarjan求lca