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未加注解,所以未打印)

监控器流程图解

原文地址:https://www.cnblogs.com/lm970585581/p/9807609.html

时间: 2024-08-09 02:54:01

springBoot @Enable*注解的工作原理的相关文章

007-Spring Boot @Enable*注解的工作原理

一.@Enable* 启用某个特性的注解 1.EnableConfigurationProperties 回顾属性装配 application.properties中添加 tomcat.host=192.168.2.1 tomcat.port=8080 增加属性类TomcatProperties package com.lhx.spring.springboot_enable; import org.springframework.boot.context.properties.Configur

Spring高级话题[email&#160;protected]***注解的工作原理

出自:http://blog.csdn.net/qq_26525215 @EnableAspectJAutoProxy @EnableAspectJAutoProxy注解 激活Aspect自动代理 <aop:aspectj-autoproxy/> 开启对AspectJ自动代理的支持. 在用到AOP的自动代理的时候用,如果你理解了Java的动态代理,很容易的就会熟悉AOP的自动代理的. @EnableAsync @EnableAsync注解开启异步方法的支持. 这个相信大家都比较熟悉的.对于异步

springboot工作原理

SpringBoot为我们做的自动配置,确实方便快捷,但一直搞不明白它的内部启动原理,这次就来一步步解开SpringBoot的神秘面纱,让它不再神秘. @SpringBootApplication   public class Application {   public static void main(String[] args) {   SpringApplication.run(Application.class, args);   }   } 从上面代码可以看出,Annotation定

@Enable*注解的原理

在SpringBoot中,我们很多的功能都能够通过@Enable*注解的方式来开启. @EnableAspectJAutoProxy开启对自动代理的支持. @EnableAsync开启异步方法的支持. @EnableConfigurationProperties开启对@ConfigurationPropertis注解配置Bean的支持. 通过Enable*一键开启对一项功能的支持,避免了自己配置大量的代码,也大大的降低了使用的难度. 我们通过观察@Enable*的这些注解,在所有的注解中都有一个

Fiori编程模型规范里注解 - @ObjectModel.readOnly工作原理解析

今天是农历鼠年大年初五,本文是鼠年第5篇文章,也是汪子熙公众号第204篇原创文章. 最近大家真是谈蝙蝠色变呀! SAP官网的ABAP Programming Model for Fiori帮助文档里,定义了很多注解(Annotation): https://help.sap.com/viewer/cc0c305d2fab47bd808adcad3ca7ee9d/1709%20000/en-US/896496ecfe4f4f8b857c6d93d4489841.html 对于这些注解,我们可以从其

Spring Boot 揭秘与实战 源码分析 - 工作原理剖析

文章目录 1. EnableAutoConfiguration 帮助我们做了什么 2. 配置参数类 – FreeMarkerProperties 3. 自动配置类 – FreeMarkerAutoConfiguration4. 扩展阅读 3.1. 核心注解 3.2. 注入 Bean 结合<Spring Boot 揭秘与实战 源码分析 - 开箱即用,内藏玄机>一文,我们再来深入的理解 Spring Boot 的工作原理. 在<Spring Boot 揭秘与实战 源码分析 - 开箱即用,内藏

Servlet生命周期、工作原理、配置

Servlet生命周期 分为三个阶段: 1,初始化阶段  调用init()方法 2,响应客户请求阶段 调用service()方法 3,终止阶段 调用destroy()方法 Servlet工作原理 每一个自定义的Servlet都必须实现Servlet的接口,Servlet接口中定义了五个方法,其中比较重要的三个方法涉及到Servlet的生命周期,分别是上文提到的init(),service(),destroy()方法.GenericServlet是一个通用的,不特定于任何协议的Servlet,它实

蓝牙及蓝牙耳机工作原理

耳机原理 蓝牙技术图片1 1 蓝牙技术的特点 1.1 蓝牙协议体系结构 整个蓝牙协议体系结构可分为底层硬件模块.中间协议层和高端应用层三大部分.链路管理层(LMP).基带层(BBP)和蓝牙无线电信道构成蓝牙的底层模块.BBP层负责跳频和蓝牙数据及信息帧的传输.LMP层负责连接的建立和拆除以及链路的安全和控制,它们为上层软件模块提供了不同的访问人口,但是两个模块接口之间的消息和数据传递必须通过蓝牙主机控制器接口的解释才能进行.也就是说,中间协议层包括逻辑链路控制与适配协议(L2CAP).服务发现协

servlet的生命周期与工作原理、使用!

概念: Servlet是一个java程序运行在服务器上,处理客户端请求并做粗响应的程序!Servlet是和平台无关的服务器组件,它运行在Servlet容器中,Servlet容器 负责servlet和客户端的交互以及调用servlet的doPost.doGet方法,采用“请求”,“响应”的模式! Servlet主要完成一下功能:   1.创建并返回基于客户端的请求的动态页面 2.可嵌入到现有的页面 3.与服务器资源(数据库.java程序)进行通信 Servlet的生命周期:  1.实例,初始化:S