springBoot @Enable*注解的工作原理
使用注解实现异步
RunnableDemo类
package com.boot.enable.bootenable; import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component; import java.util.concurrent.TimeUnit; @Component
public class RunnableDemo implements Runnable { @Async // 异步方式执行方法
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("----------------"+ (i +1));
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
测试类
package com.boot.enable.bootenable; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.EnableAsync; @SpringBootApplication
@EnableAsync
public class BootEnableApplication { public static void main(String[] args) {
ConfigurableApplicationContext context =
SpringApplication.run(BootEnableApplication.class, args);
Runnable bean = context.getBean(Runnable.class);
System.out.println("-----------start-----------");
bean.run();
System.out.println("-----------end-----------"); context.close();
}
}
运行结果分析:
run方法打印的内容是异步进行的,是独立于主线程外的线程,所以-----------end-----------打印后,run方法依然再进行打印

几种装配方式
1.普通的方式
package com.boot.enable.imp.demo;
public class Book {
}
package com.boot.enable.imp.demo; import org.springframework.stereotype.Component; @Component
public class User {
}
package com.boot.enable.imp.demo; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean; /**
* 普通方式装配
*/
@SpringBootApplication
public class ImportApplication { @Bean
public Book book() {
return new Book();
} public static void main(String[] args) {
ConfigurableApplicationContext context =
SpringApplication.run(ImportApplication.class, args);
System.out.println(context.getBean(User.class));
System.out.println(context.getBean(Book.class)); context.close();
}
}
使用@Import装配的第一种方式
package com.boot.enable.imp.demo1;
public class Book {
}
package com.boot.enable.imp.demo1;
public class User {
}
package com.boot.enable.imp.demo1; import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata; public class BeanImportSelector implements ImportSelector {//不需要注入其他属性时使用
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.boot.enable.imp.demo1.Book"
,"com.boot.enable.imp.demo1.User"};
}
}
package com.boot.enable.imp.demo1; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import; /**
* 使用@Import方式装配
*/
@SpringBootApplication
// @Import({User.class, Book.class})
@Import(BeanImportSelector.class)
public class ImportApplication1 { public static void main(String[] args) {
ConfigurableApplicationContext context =
SpringApplication.run(ImportApplication1.class, args);
System.out.println(context.getBean(User.class));
System.out.println(context.getBean(Book.class)); context.close();
}
}
使用@Import装配 第二种方式
package com.boot.enable.imp.demo2; 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; public class MyBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {//有属性注入时使用
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 创建构建器对象
BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(User.class);
BeanDefinition beanDefinition = bdb.getBeanDefinition();
registry.registerBeanDefinition("user", beanDefinition); BeanDefinitionBuilder bdb1 = BeanDefinitionBuilder.rootBeanDefinition(Book.class);
BeanDefinition beanDefinition1 = bdb1.getBeanDefinition();
registry.registerBeanDefinition("book", beanDefinition1);
}
}
package com.boot.enable.imp.demo2; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import; /**
* 使用@Import方式装配
*/
@SpringBootApplication
@Import(MyBeanDefinitionRegistrar.class)
public class ImportApplication1 { public static void main(String[] args) {
ConfigurableApplicationContext context =
SpringApplication.run(ImportApplication1.class, args);
System.out.println(context.getBean("user",User.class));
System.out.println(context.getBean(Book.class)); context.close();
}
}
实例演示:注解注册监控器实现
实体类准备:
package com.boot.enable.sample.bean; import org.springframework.stereotype.Component; @Component
public class Person {
}
public class Person1 {
}
package com.boot.enable.sample.bean; import org.springframework.stereotype.Component; @Component
public class Person2 {
}
package com.boot.enable.sample.vo; import org.springframework.stereotype.Component; @Component
public class UserVO {
}
自定义一个注解(借用@Import机制)
package com.boot.enable.sample; import org.springframework.context.annotation.Import; import java.lang.annotation.*; @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(ScannerPackageRegistrar.class)
public @interface EnableScanner {
String[] packages();
}
package com.boot.enable.sample; 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 java.util.Arrays;
import java.util.List; public class ScannerPackageRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
String[] attrs = (String[]) importingClassMetadata
.getAnnotationAttributes(EnableScanner.class.getName())
.get("packages");//获取到注解的packages属性
List<String> packages = Arrays.asList(attrs);
System.out.println(packages);
BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(MyBeanDefinitionProcessor.class);
bdb.addPropertyValue("packages", packages);//注入属性 registry.registerBeanDefinition(MyBeanDefinitionProcessor.class.getName(), bdb.getBeanDefinition());//装配到Spring容器中 }
}
package com.boot.enable.sample; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor; import java.util.List; public class MyBeanDefinitionProcessor implements BeanPostProcessor { private List<String> packages; public List<String> getPackages() {
return packages;
} public void setPackages(List<String> packages) {
this.packages = packages;
} @Override//扫描出装配到容器中的类并打印出对应实例
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
for (String pack : packages) { if (bean.getClass().getName().startsWith(pack)) {
System.out.println("instance bean:"+bean.getClass().getName());
}
}
return bean;
}
}
测试类
package com.boot.enable.sample; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext; /**
* 普通方式装配
*/
@SpringBootApplication
@EnableScanner(packages ={"com.boot.enable.sample.bean","com.boot.enable.sample.vo"}) // 启用监控扫描类的注解
public class ScannerPackageApplication { public static void main(String[] args) {
ConfigurableApplicationContext context =
SpringApplication.run(ScannerPackageApplication.class, args);
context.close(); new ScannerPackageApplication().callFunction(new FunctionImpl());//回调演示
} interface Function {
void hello();
} static class FunctionImpl implements Function { @Override
public void hello() {
System.out.println("调用了FunctionImpl->Hello方法");
}
} public void callFunction(Function fun) {
//处理其他事
fun.hello(); //回调
//处理其他事
}
}
打印结果(打印出注入到Spring容器中的实例,Person1未加注解,所以未打印)

监控器流程图解

springBoot @Enable*注解的工作原理的更多相关文章
- Spring高级特性之三:@Enable*注解的工作原理
Spring Boot中阐述热插拔技术的时候,简单地提及@Enable*注解.随着多种框架的应用及深入了解,@Enable*这个注解在各种框架中应用相当普及. 那么@Enable*注解工作原理是怎么样 ...
- Spring高级话题-@Enable***注解的工作原理
出自:http://blog.csdn.net/qq_26525215 @EnableAspectJAutoProxy @EnableAspectJAutoProxy注解 激活Aspect自动代理 & ...
- Spring的@Enable*注解的工作原理
转自:https://blog.csdn.net/chengqiuming/article/details/81586948 一 列举几个@Enable*注解的功能 @EnableAspectJAut ...
- @Enable*注解的工作原理
@EnableAspectJAutoProxy @EnableAsync @EnableScheduling @EnableWebMv @EnableConfigurationProperties @ ...
- 自定义Spring-Boot @Enable注解
Spring-Boot中有很多Enable开头的注解,通过添加注解来开启一项功能,如 其原理是什么?如何开发自己的Enable注解? 1.原理 以@EnableScheduling为例,查看其源码,发 ...
- EnableAutoConfiguration注解的工作原理(org.springframework.boot.autoconfigure.EnableAutoConfiguration=core.bean.MyConfig)
EnableAutoConfiguration注解的工作原理(org.springframework.boot.autoconfigure.EnableAutoConfiguration=core.b ...
- 007-Spring Boot-@Enable*注解的工作原理-EnableConfigurationProperties、ImportSelector、ImportBeanDefinitionRegistrar
一.@Enable* 启用某个特性的注解 1.EnableConfigurationProperties 回顾属性装配 application.properties中添加 tomcat.host=19 ...
- 注解 @EnableFeignClients 工作原理
概述在Spring cloud应用中,当我们要使用feign客户端时,一般要做以下三件事情 : 使用注解@EnableFeignClients启用feign客户端:示例 : @SpringBootAp ...
- Spring Boot @Enable*注解源码解析及自定义@Enable*
Spring Boot 一个重要的特点就是自动配置,约定大于配置,几乎所有组件使用其本身约定好的默认配置就可以使用,大大减轻配置的麻烦.其实现自动配置一个方式就是使用@Enable*注解,见其名知 ...
随机推荐
- Java-谈谈对Java平台的理解
问题 谈谈对 Java 平台的理解 Java是解释执行的 这句话对么 程序的编译与解释有什么区别 Java 平台的了解 Java的主要特点是两个, 编写一次到处运行 Write once, run a ...
- 利用cross-entropy cost代替quadratic cost来获得更好的收敛
1.从方差代价函数说起(Quadratic cost) 代价函数经常用方差代价函数(即采用均方误差MSE),比如对于一个神经元(单输入单输出,sigmoid函数),定义其代价函数为: 其中y是我们期望 ...
- 记一次 Android 客户端(CJYYKT)的逆向
主角: 描述: 湖南省教育局推的一款大学生 App,需要每个学生看完里面的一个课程的视频,共 8 章,每章 10 - 23 个视频(连续播放大约 24 小时),每个视频每隔不定时间就会弹出一个选择题答 ...
- 屏蔽Drupal中的“Notice: Undefined index”警告
原因:drupal默认使用E_ALL,即输出所有错误和警告.我们只需要修改错误显示级别即可. 方法: 1. 打开\sites\default\settings.php 追加一行 ini_set('er ...
- 聊聊WS-Federation
本文来自网易云社区 单点登录(Single Sign On),简称为 SSO,目前已经被大家所熟知.简单的说, 就是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统. 举例: 我们 ...
- K8S全栈容器服务如何助力企业云化创新?
容器编排管理平台Kubernetes在实践两年多后,市场主导地位被正式确定,随着首批认证服务商的宣布,围绕着容器的应用编排部署服务已然成熟,Kubernetes开始在商业场景为企业创造价值.华为云在K ...
- Unity Android设备的输入
Unity Android设备的输入 1依据屏幕位置输入 有的时候也许是为了整个有些风格的干净,减少屏幕上的UI图标,以至于摒弃了虚拟按键这种常用的输入方式.为了替代虚拟按键的输入方式而选择了依据点击 ...
- 【system.date】使用说明
对象:system.date 说明:提供一系列针对日期类型的操作 目录: 方法 返回 说明 system.date.isDate( date_string ) [True | False] 判断 ...
- python常用命令—查看模块所在位置
环境:ipython3 交互式解释器 语法: import 模块名 模块名.__file__ 功能: 查看模块的所在位置 例:
- C++ 学习笔记之——STL 库 vector
vector 是一种顺序容器,可以看作是可以改变大小的数组. 就像数组一样,vector 占用连续的内存地址来存储元素,因此可以像数组一样用偏移量来随机访问,但是它的大小可以动态改变,容器会自动处理内 ...