前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Springboot自动装配整理

Springboot自动装配整理

作者头像
算法之名
发布2019-11-23 08:41:57
4310
发布2019-11-23 08:41:57
举报
文章被收录于专栏:算法之名

首先写一个我们自己的HelloWorld配置类

1、基于"注解驱动"实现@Enable模块

代码语言:javascript
复制
@Configuration
public class HelloWorldConfiguration {
    @Bean
    public String helloWorld() {
        return "Hello,World";
    }
}

再模仿Spring Cloud Feign源码解析 中的@EnableFeignClients代码写一个我们自己的标签

代码语言:javascript
复制
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(HelloWorldConfiguration.class)
public @interface EnableHelloWorld {
}

@EnableFeignClients Import的是FeignClientsRegistrar.class,而我们这里导入的是HelloWorldConfiguration.class

再编写一个引导类来看一下效果。

代码语言:javascript
复制
@EnableHelloWorld
@Configuration
public class EnabledHelloWorldBootstrap {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(EnabledHelloWorldBootstrap.class);
        context.refresh();
        String helloWorld = context.getBean("helloWorld", String.class);
        System.out.printf("helloWorld = %s \n",helloWorld);
        context.close();
    }
}

运行结果(部分)

15:00:46.060 main DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'lifecycleProcessor'

15:00:46.065 main DEBUG org.springframework.core.env.PropertySourcesPropertyResolver - Could not find key 'spring.liveBeansView.mbeanDomain' in any property source

15:00:46.069 main DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'helloWorld'

helloWorld = Hello,World

15:00:46.069 main INFO org.springframework.context.annotation.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@31a5c39e: startup date Thu Nov 21 15:00:45 CST 2019; root of context hierarchy

15:00:46.070 main DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'lifecycleProcessor'

15:00:46.070 main DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5427c60c: defining beans org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,enabledHelloWorldBootstrap,com.cloud.demo.config.HelloWorldConfiguration,helloWorld; root of factory hierarchy

2、基于"接口编程"实现@Enable模块

基于ImportSelector接口实现

假设当前应用支持两种服务类型:HTTP和FTP,通过@EnableServer设置服务器类型(type)提供对应的服务

先定义一个服务接口

代码语言:javascript
复制
public interface Server {
    /**
     * 启动服务器
     */
    void start();

    /**
     * 关闭服务器
     */
    void stop();

    /**
     * 服务器类型
     */
    enum Type {
        HTTP, //HTTP服务器
        FTP   //FTP服务器
    }
}

两个实现类

代码语言:javascript
复制
@Component
public class HTTPServer implements Server {
    @Override
    public void start() {
        System.out.println("HTTP服务器启动中...");
    }

    @Override
    public void stop() {
        System.out.println("HTTP服务器关闭中...");
    }
}
代码语言:javascript
复制
@Component
public class FTPServer implements Server {
    @Override
    public void start() {
        System.out.println("FTP服务器启动中...");
    }

    @Override
    public void stop() {
        System.out.println("FTP服务器关闭中...");
    }
}

实现@Enable模块驱动

代码语言:javascript
复制
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(ServerImportSelector.class)
public @interface EnableServer {
    /**
     * 设置服务器类型
     * @return
     */
    Server.Type type();
}

实现Server ImportSelector接口

代码语言:javascript
复制
public class ServerImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        //读取EnableServer中所有的属性方法,本例中仅有type()属性方法
        //其中key为属性方法的名称,value为属性方法的返回对象
        Map<String,Object> annotationAttributes = importingClassMetadata
                .getAnnotationAttributes(EnableServer.class.getName());
        //获取名为type的属性方法,并且强制转换成Server.Type类型
        Server.Type type = (Server.Type) annotationAttributes.get("type");
        //导入的类名称数组
        String[] importClassNames = new String[0];
        switch (type) {
            case HTTP:
                importClassNames = new String[]{HTTPServer.class.getName()};
                break;
            case FTP:
                importClassNames = new String[]{FTPServer.class.getName()};
                break;
        }
        return importClassNames;
    }
}

标注@EnableServer到引导类EnableServerBootstrap

代码语言:javascript
复制
@Configuration
@EnableServer(type = Server.Type.HTTP)
public class EnableServerBootstrap {
    public static void main(String[] args) {
        //构建Annotation配置驱动Spring上下文
        AnnotationConfigApplicationContext context = new
                AnnotationConfigApplicationContext();
        //注册当前引导类(被@Configuration标注)到Spring上下文
        context.register(EnableServerBootstrap.class);
        //启动上下文
        context.refresh();
        //获取Server Bean对象,实际为HttpServer
        Server server = context.getBean(Server.class);
        //启动服务器
        server.start();
        //关闭服务器
        server.stop();
    }
}

运行结果(部分)

16:52:08.966 main DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Unable to locate LifecycleProcessor with name 'lifecycleProcessor': using default org.springframework.context.support.DefaultLifecycleProcessor@2fb3536e

16:52:08.967 main DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'lifecycleProcessor'

16:52:08.975 main DEBUG org.springframework.core.env.PropertySourcesPropertyResolver - Could not find key 'spring.liveBeansView.mbeanDomain' in any property source

16:52:08.979 main DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'com.cloud.demo.server.HTTPServer'

HTTP服务器启动中...

HTTP服务器关闭中...

基于ImportBeanDefinitionRegistrar接口实现

替换上例中的ServerImportSelector即可

代码语言:javascript
复制
public class ServerImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        //复用 {@link ServerImportSelector} 实现,避免重复劳动
        ImportSelector importSelector = new ServerImportSelector();
        //筛选Class名称集合
        String[] selectedClassNames = importSelector.selectImports(importingClassMetadata);
        //创建Bean定义
        Stream.of(selectedClassNames)
                //转化为BeanDefinitionBuilder对象
                .map(BeanDefinitionBuilder::genericBeanDefinition)
                //转化为BeanDefinition
                .map(BeanDefinitionBuilder::getBeanDefinition)
                //注册BeanDefinition到BeanDefinitionRegistry
                .forEach(beanDefinition -> BeanDefinitionReaderUtils
                        .registerWithGeneratedName(beanDefinition,registry));
    }
}

替换@EnableServer的@Import

代码语言:javascript
复制
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(ServerImportBeanDefinitionRegistrar.class)
public @interface EnableServer {
    /**
     * 设置服务器类型
     * @return
     */
    Server.Type type();
}

运行结果

17:38:53.147 main DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'lifecycleProcessor'

17:38:53.150 main DEBUG org.springframework.core.env.PropertySourcesPropertyResolver - Could not find key 'spring.liveBeansView.mbeanDomain' in any property source

17:38:53.152 main DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'com.cloud.demo.server.HTTPServer#0'

HTTP服务器启动中...

HTTP服务器关闭中...

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档