纵有疾风起
人生不言弃

springBoot @Enable*注解的工作原理


使用注解实现异步

RunnableDemo

 

package com.boot.enable.bootenable;import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Component;import java.util.concurrent.TimeUnit;@Componentpublic 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@EnableAsyncpublic 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方法依然再进行打印

springBoot @Enable*注解的工作原理插图

几种装配方式

1.普通的方式

package com.boot.enable.imp.demo;public class Book {}
package com.boot.enable.imp.demo;import org.springframework.stereotype.Component;@Componentpublic 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;/** * 普通方式装配 */@SpringBootApplicationpublic 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;@Componentpublic class Person {}
public class Person1 {}
package com.boot.enable.sample.bean;import org.springframework.stereotype.Component;@Componentpublic class Person2 {}
package com.boot.enable.sample.vo;import org.springframework.stereotype.Component;@Componentpublic 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*注解的工作原理插图(1)

 

 监控器流程图解

springBoot @Enable*注解的工作原理插图(2)

 

文章转载于:https://www.cnblogs.com/lm970585581/p/9807609.html

原著是一个有趣的人,若有侵权,请通知删除

未经允许不得转载:起风网 » springBoot @Enable*注解的工作原理

分享到: 生成海报
avatar

评论 抢沙发

评论前必须登录!

立即登录   注册

切换注册

登录

忘记密码 ?

切换登录

注册

我们将发送一封验证邮件至你的邮箱, 请正确填写以完成账号注册和激活