# test2-springboot **Repository Path**: shiyichan/test2-springboot ## Basic Information - **Project Name**: test2-springboot - **Description**: No description available - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-04-10 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 实验二 利用Spring boot的自动装配特性实现动态注册组件 学号:201741412218   姓名:陈诗怡     班级:17软卓2班     指导老师:黎志雄     实验日期:2020.4.12 ## 一、实验目标 1. 掌握Spring Boot的自动配置原理; 2. 掌握Spring框架动态注册Bean的原理; 3. 掌握自动生成元数据文件。 4. 掌握spring框架的事件模型。 ## 二、实验条件 1、JDK1.8或更高版本 2、Maven3.6+ 3、IntelliJ-IDEA ## 三、实验内容 #### 1、通过IntelliJ IDEA的Spring Initializr向导创建Spring Boot项目;   File->new Project->选择Spring Initializr->选择添加Spring Configuration Processor依赖,具体如下图:
#### 2、创建一个自定义的CommandLineRunner接口的实现类; ``` public class CustomCommandLineRunner implements CommandLineRunner { Environment env; //使用构造方法的方式注入Environment public CustomCommandLineRunner(Environment env){ this.env = env; } @Override public void run(String... args){ System.out.println("利用Spring Boot自动装配的CommandLineRunner. "); //利用random的RandomValuePropertySource产生一个32位随机字串 System.out.println("生成一个随机字符串:".concat(Objects.requireNonNull(env.getProperty("random.")))); } } ``` #### 3、创建一个自定义的自动配置类; ``` public class CustomCommandLineRunner implements CommandLineRunner { Environment env; //使用构造方法的方式注入Environment public CustomCommandLineRunner(Environment env){ this.env = env; } @Override public void run(String... args){ System.out.println("利用Spring Boot自动装配的CommandLineRunner. "); //利用random的RandomValuePropertySource产生一个32位随机字串 System.out.println("生成一个随机字符串:".concat(Objects.requireNonNull(env.getProperty("random.")))); } } ``` #### 4、创建spring.factories文件; #### `步骤`: (1)先在resources文件目录下创建一个名为META-INF的的文件,再在该文件目录下创建spring.factories文件,创建结果如图:
(2)在spring.factories文件输入以下内容:
  key必须是EnableAutoConfiguration的全限定类名,值为刚才我们自定义的自动配置类的全限定类路径的类名。 ##### 测试运行程序:
##### 运行结果:
#### 5、给自动配置类添加有效条件; #### `步骤`: (1)利用@ConditionalOnProperty注解,添加属性条件;
(2)在application.properties属性文件中添加一个自定义的属性; ``` test2.auto.enable=true ```   运行结果如图:
(3)切换属性值false,观察终端的显示,判断自动装配的配置类是否生效; ``` test2.auto.enable=false ```   运行结果如下,自动装配的配置类已生效:
#### 6、自定义的一个Bean,绑定属性值,并生成spring配置类的元数据文件; #### `步骤` : (1)创建一个类,并在类上加@ConfigurationProperties注解,设置注解的prefix属性指定绑定的属性的前缀;
(2)在某个配置类上添加@EnableConfigurationProperties,并指定装配的属性Bean;
(3)使用spring boot框架提供的注解处理器生成自定义属性的元数据文件。 ##### `说明`: ``` Spring Boot应程序打包后的jar文件中包含元数据文件,这些文件提供了所有受支持的配置属性的详细信息。这些文件旨在让IDE开发人员在编辑application.properties或application.yml文件时提供上下文帮助和“代码完成” 。Interllj IDEA默认支持。 元数据文件位于META-INF目录下,名字spring-configuration-metadata.json。 元数据文件可以自己写,或使用spring boot官方提供的依赖包自动生成。 在pom.xml文件中引入spring-boot-configuration-processor依赖。这个依赖包里有spring boot提供的注解处理器,在项目编译时检查项目内所有@ConfigurationProperties的类,并生成元数据文件。 ```   a.在pom.xml文件中引入spring-boot-configuration-processor依赖:
  b.编译打包项目。观察target目录下的元数据文件:
  c.现在我们再回去编辑属性文件时,只要输入属性的部分关键字,idea会自动提示,如下图:
#### 7、根据阅读框架源码,我们可以自定义一个事件发布器,并设置线程池,实现异步发布事件; > 自定义事件发布器: ``` /** * 自定义事件发布器 * @param taskExecutor{@Link ThreadPoolTaskExecutor} * @return ApplicationEventMulticaster {@Link SimpleApplicationEventMulticaster} */ @Bean(AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME) ApplicationEventMulticaster customApplicationEventMulticaster(ThreadPoolTaskExecutor taskExecutor){ SimpleApplicationEventMulticaster eventMulticaster = new SimpleApplicationEventMulticaster(); eventMulticaster.setTaskExecutor(taskExecutor); return eventMulticaster; } ``` #### 8、自定义事件类; ``` public static class NoticeEvent extends ApplicationEvent { private static final Logger logger= LoggerFactory.getLogger(NoticeEvent.class); /** * 储存信息 */ private final String message; public NoticeEvent(String message){ super(message); this.message=message; logger.info("添加事件成功!message: {}",message); } public String getMessage(){ return message; } } ``` #### 8、自定义事件监听器; ``` /** * 自定义事件监听器,监听{@Link NoticeEvent}事件 */ @Component static class NoticeListener implements ApplicationListener{ private static final Logger logger = LoggerFactory.getLogger(NoticeListener.class); @Override public void onApplicationEvent(NoticeEvent noticeEvent){ logger.info("事件监听器获取到 NoticeEvent,睡眠当前线程2秒..."); try{ Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } logger.info("NoticeEvent 的 message属性是:{}",noticeEvent.getMessage()); } } ``` #### 10、编写一个测试用例,检查发布事件时,是否使用了多线程异步处理; ``` @SpringBootTest class SpringbootTest2ApplicationTests { @Autowired ApplicationEventMulticaster eventMulticaster; @Test void contextLoads() throws InterruptedException{ eventMulticaster.multicastEvent(new AutoConfig.NoticeEvent("chenshiyi")); eventMulticaster.multicastEvent(new AutoConfig.NoticeEvent("Spring Boot lab2 test...")); //睡眠单元测试主线程2.1秒,避免单元测试主线程结束时异步事件的线程还没有结束而报异常。 Thread.sleep(2100); } } ``` >运行单元测试结果如下: ![输入图片说明](https://images.gitee.com/uploads/images/2020/0412/130502_1bccd2ff_4846765.png "运行测试结果.png") ## 四、实验总结 ``` 1.本次实验通过Spring Initializr向导创建Spring Boot项目,是很便捷的方法,在构建的时候配置选择需要的依赖即可,pom.xml会自动编写好,很方便。 2.本次实验让我们进一步掌握了解了spring boot的自动配置原理。 3.本次实验让我们掌握了Spring框架动态注册Bean的原理,和自动生成元数据文件的操作 4.通过自定义事件发布器、事件类和事件监听器进行测试,我们进一步了解了spring框架的事件模型 ```