版权声明:本文为博主原创文章,未经博主允许不得转载 https://blog.csdn.net/Andy2019/article/details/82948801
一、读取配置文件
--application.properties
tomcat.host=192.168.1.1
tomcat.port=8080
package vip.fkandy.model;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "tomcat")
public class TomcatProperties {
private String host;
private String port;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
@Override
public String toString() {
return "TomcatProperties [host=" + host + ", port=" + port + "]";
}
}
package vip.fkandy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import vip.fkandy.model.TomcatProperties;
/**
* @author chenjianfei
*/
//@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
System.out.println(context.getBean(TomcatProperties.class));
}
}
@SpringBootApplication中用来读取配置文件的主要注解是@@EnableAutoConfiguration(AutoConfigurationImportSelector)和
@ComponentScan
二、Spring Boot使用异步
package vip.fkandy;
import java.util.concurrent.TimeUnit;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@Component
public class MyRunnable implements Runnable {
@Async
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
System.out.println("------" + i);
TimeUnit.SECONDS.sleep(1);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package vip.fkandy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.EnableAsync;
import vip.fkandy.model.TomcatProperties;
/**
* @EnableAutoConfiguration 用来启用一个特性:可以把配置文件的属性注入到Bean里面
* @EnableAsync 用来启用异步执行特性,在需要异步执行的方法上添加@Async注解
* @author chenjianfei
*
*/
@SpringBootApplication
@EnableAsync
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
System.out.println(context.getBean(TomcatProperties.class));
context.getBean(Runnable.class).run();
System.out.println("-------end-------");
}
}
异步操作类:AsyncConfigurationSelector
三、ImportSelector原理 读取注解内容
package vip.fkandy.config;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(MyImportSelector.class)
public @interface EnableLog {
String name();
}
package vip.fkandy.config;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
import vip.fkandy.model.User;
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
/**
* 这里可以获取到注解的详细信息,然后根据信息去动态返回需要被Spring 容器管理的bean
*/
System.out.println("---" + importingClassMetadata.getAnnotationAttributes(EnableLog.class.getName()));
return new String[] { User.class.getName() };
}
}
package vip.fkandy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.EnableAsync;
import vip.fkandy.config.EnableLog;
import vip.fkandy.model.TomcatProperties;
/**
* @EnableAutoConfiguration 用来启用一个特性:可以把配置文件的属性注入到Bean里面
* @EnableAsync 用来启用异步执行特性,在需要异步执行的方法上添加@Async注解
* @author chenjianfei
*
*/
@SpringBootApplication
@EnableAsync
@EnableLog(name = "my spring boot test annotation")
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
System.out.println(context.getBean(TomcatProperties.class));
context.getBean(Runnable.class).run();
System.out.println("-------end-------");
}
}
四、ImportBeanDefinitionRegistrar原理(无返回值,需要自己通过BeanDefinitionRegistry注入bean)
package vip.fkandy.model;
public class User {
}
package vip.fkandy.config;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(MyImportBeanDefinitionRegistrar.class)
public @interface EnableLog {
String name();
}
package vip.fkandy.config;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import vip.fkandy.model.User;
/**
* 向Spring容器注入User
*
* @author chenjianfei
*
*/
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(User.class);
BeanDefinition beanDefinition = builder.getBeanDefinition();
registry.registerBeanDefinition("user", beanDefinition);
}
}
package vip.fkandy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.EnableAsync;
import vip.fkandy.config.EnableLog;
import vip.fkandy.model.User;
/**
* @EnableAutoConfiguration 用来启用一个特性:可以把配置文件的属性注入到Bean里面
* @EnableAsync 用来启用异步执行特性,在需要异步执行的方法上添加@Async注解
* @author chenjianfei
*
*/
@SpringBootApplication
@EnableAsync
@EnableLog(name = "my spring boot test annotation")
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
System.out.println(context.getBean(User.class));
System.out.println("-------end-------");
}
}
五、Enable和Import结合使用demo
package vip.fkandy.config;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EchoImportBeanDefinitionRegistrar.class)
public @interface EnableEcho {
String[] packages();
}
package vip.fkandy.config;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
public class EchoImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
Map<String, Object> annotationAttributes = importingClassMetadata
.getAnnotationAttributes(EnableEcho.class.getName());
String[] packArray = (String[]) annotationAttributes.get("packages");
List<String> packages = Arrays.asList(packArray);
System.out.println("packages :" + packages);
BeanDefinitionBuilder beanBuilder = BeanDefinitionBuilder.rootBeanDefinition(EchoBeanPostProcessor.class);
beanBuilder.addPropertyValue("packages", packages);
registry.registerBeanDefinition(EchoBeanPostProcessor.class.getName(), beanBuilder.getBeanDefinition());
}
}
package vip.fkandy.config;
import java.util.List;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class EchoBeanPostProcessor implements BeanPostProcessor {
private List<String> packages;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
for (String pack : packages) {
if (bean.getClass().getName().startsWith(pack)) {
System.out.println("echo bean :" + bean.getClass().toGenericString());
}
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
public List<String> getPackages() {
return packages;
}
public void setPackages(List<String> packages) {
this.packages = packages;
}
}
package vip.fkandy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.EnableAsync;
import vip.fkandy.config.EnableEcho;
import vip.fkandy.config.EnableLog;
/**
* @EnableAutoConfiguration 用来启用一个特性:可以把配置文件的属性注入到Bean里面
* @EnableAsync 用来启用异步执行特性,在需要异步执行的方法上添加@Async注解
* @author chenjianfei
*
*/
@SpringBootApplication
@EnableAsync
@EnableLog(name = "my spring boot test annotation")
@EnableEcho(packages = "vip.fkandy.model")
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
System.out.println("-------end-------");
}
}
日志
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.5.RELEASE)
2018-10-06 09:07:05.425 INFO 13196 --- [ main] vip.fkandy.Application : Starting Application on DESKTOP-6FVEB35 with PID 13196 (D:\STS_4.0\workspace\00\springboot-2\target\classes started by chenjianfei in D:\STS_4.0\workspace\00\springboot-2)
2018-10-06 09:07:05.444 INFO 13196 --- [ main] vip.fkandy.Application : No active profile set, falling back to default profiles: default
2018-10-06 09:07:05.598 INFO 13196 --- [ main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@389b0789: startup date [Sat Oct 06 09:07:05 CST 2018]; root of context hierarchy
packages :[vip.fkandy.model]
2018-10-06 09:07:07.821 INFO 13196 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2018-10-06 09:07:07.860 INFO 13196 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2018-10-06 09:07:07.861 INFO 13196 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.34
2018-10-06 09:07:07.879 INFO 13196 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [D:\jdk1.8.0_161\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;D:\jdk1.8.0_161\jre\bin;D:/jdk1.8.0_161/bin/../jre/bin/server;D:/jdk1.8.0_161/bin/../jre/bin;D:/jdk1.8.0_161/bin/../jre/lib/amd64;D:\app\chenjianfei\product\11.2.0\client_1\bin;C:\Program Files (x86)\Intel\iCLS Client\;C:\Program Files\Intel\iCLS Client\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;D:\jdk1.8.0_161\bin;D:\apache-maven-3.5.2\bin;D:\Git\cmd;D:\gradle-4.5\bin;D:\scala-2.12.6\bin;D:\zookeeper-3.4.12\bin;D:\Program Files\TortoiseSVN\bin;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Users\chenjianfei\AppData\Local\Microsoft\WindowsApps;C:\Users\chenjianfei\AppData\Local\GitHubDesktop\bin;D:\STS_4.0;;.]
2018-10-06 09:07:08.116 INFO 13196 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2018-10-06 09:07:08.117 INFO 13196 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2522 ms
2018-10-06 09:07:08.221 INFO 13196 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
2018-10-06 09:07:08.227 INFO 13196 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-10-06 09:07:08.228 INFO 13196 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-10-06 09:07:08.228 INFO 13196 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-10-06 09:07:08.228 INFO 13196 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
echo bean :public class vip.fkandy.model.TomcatProperties
echo bean :public class vip.fkandy.model.User
2018-10-06 09:07:08.467 INFO 13196 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-10-06 09:07:08.758 INFO 13196 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@389b0789: startup date [Sat Oct 06 09:07:05 CST 2018]; root of context hierarchy
2018-10-06 09:07:08.876 INFO 13196 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2018-10-06 09:07:08.878 INFO 13196 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-10-06 09:07:09.035 INFO 13196 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-10-06 09:07:09.037 INFO 13196 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-10-06 09:07:09.238 INFO 13196 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2018-10-06 09:07:09.288 INFO 13196 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2018-10-06 09:07:09.295 INFO 13196 --- [ main] vip.fkandy.Application : Started Application in 4.433 seconds (JVM running for 5.256)
-------end-------