前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ApplicationInitlizer接口与Spring工具类

ApplicationInitlizer接口与Spring工具类

作者头像
写一点笔记
发布2022-08-11 17:00:53
3140
发布2022-08-11 17:00:53
举报
文章被收录于专栏:程序员备忘录程序员备忘录

项目中要灵活使用static来标记一些常用得类,static得作用就是跨对象得存在性。只要类没有被卸载掉,那么static修饰得属性就一直在。因此我们可以用static来标记一些引用,因为static一直存在,那么我们通过static得修饰就可以获得其引用得地址,不论被应用得对象身处何方。 有了上述思想,我们就能想到在spring框架中,上下文是我们重点关切得对象。因此我们想着通过static来引用spring上下文,然后形成一个工具类。我们在项目得业务部分能够通过该工具类来操作我们得spring上下文。这块我们说一下spring扩展接口ApplicationContextInitializer,这个接口会在spring上下文刷新之前进行调用,相当于提前将容器进行对外得暴露,当然页提供了我们修改其属性得权力。ApplicationContextInitializer得执行在prepareContext中,这块之前也大概得说过了。

我们通过查看源码,发现这块传入得是ConfigurableApplicationContext,注意这块返回得是空,意思是我们可以对这里得context进行应用标记。

代码语言:javascript
复制
protected void applyInitializers(ConfigurableApplicationContext context) {
        Iterator var2 = this.getInitializers().iterator();
        while(var2.hasNext()) {
            ApplicationContextInitializer initializer = (ApplicationContextInitializer)var2.next();
            Class requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(), ApplicationContextInitializer.class);
            Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
            initializer.initialize(context);
        }
}

通过以上得分析,我们就想这在initialize方法中将我们得上下文缓存进来。让我们来做个实践吧。

代码语言:javascript
复制
public class MyBean {

    private String name;

    private String config;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getConfig() {
        return config;
    }


    public void setConfig(String config) {
        this.config = config;
    }

    @Override
    public String toString() {
        return "MyBean{" +
                "name='" + name + '\'' +
                ", config='" + config + '\'' +
                '}';
    }
}

静态Spring工具类

代码语言:javascript
复制
public class MySpringContentUtils {


    public static ConfigurableApplicationContext context;


    public static ConfigurableApplicationContext getContext() {
        return context;
    }


    public static void setContext(ConfigurableApplicationContext context) {
        MySpringContentUtils.context = context;
    }


    public static void registerBean(String name, Class factoryClazz, Class beanClazz, MutablePropertyValues mpv) throws BeanDefinitionStoreException {
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(beanClazz);
        GenericBeanDefinition beanDefinition = (GenericBeanDefinition)beanDefinitionBuilder.getRawBeanDefinition();
        beanDefinition.setBeanClass(factoryClazz == null ? beanClazz : factoryClazz);
        beanDefinition.setPropertyValues(mpv);
        BeanDefinitionRegistry beanFactory = (BeanDefinitionRegistry)context.getBeanFactory();
        beanFactory.registerBeanDefinition(name, beanDefinition);
    }


    public staticT getBean(String name) throws BeansException {
        return (T) context.getBean(name);
    }
}

自定义initlizer接口

代码语言:javascript
复制
public class MyTianApplicationInitlize implements ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        System.out.println("我来了...宝");
        MySpringContentUtils.setContext(configurableApplicationContext);
    }
}

测试类

代码语言:javascript
复制
    public static void main(String[] args) throws InterruptedException {
        SpringApplication builder=new SpringApplicationBuilder(Demo1Application.class).initializers(new MyTianApplicationInitlize()).build();
        builder.run( args);
        System.out.println(env.toString());
        MutablePropertyValues mpv = new MutablePropertyValues();
        mpv.addPropertyValue("name","tianjingle_initlizer");
        MySpringContentUtils.registerBean("lisi",null, MyBean.class,mpv);
        MyBean myBean= (MyBean) MySpringContentUtils.getContext().getBean("lisi");
        System.out.println(myBean.toString());
    }

效果

通过上述实践,我们实现了我们得目标。当然我们也可以采用spring.factories文件得方式进行添加initlizer工具。这种方式在springBoot中得starter中用得比较多,看这里。

响应得修改我们得启动类

代码语言:javascript
复制
    public static void main(String[] args) throws InterruptedException {
//        SpringApplication builder=new SpringApplicationBuilder(Demo1Application.class).initializers(new MyTianApplicationInitlize()).build();
//        builder.run( args);
        SpringApplication.run(Demo1Application.class,args);
        System.out.println(env.toString());
        MutablePropertyValues mpv = new MutablePropertyValues();
        mpv.addPropertyValue("name","tianjingle_initlizer");
        MySpringContentUtils.registerBean("lisi",null, MyBean.class,mpv);
        MyBean myBean= (MyBean) MySpringContentUtils.getContext().getBean("lisi");
        System.out.println(myBean.toString());
    }

至于spring.factories文件得读取,这个在启动得时候springBoot就会加载。就说这么多吧。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-07-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 写点笔记 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档