前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >BeanFactory动态注入到Interface

BeanFactory动态注入到Interface

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

有时候代码需要灵活的返回需要的一些对象,这时候我们往往用接口去承载返回的对象。尤其像spring这种框架,可以用@Resource的name属性进行区别。但是这种需要开发者在注入ioc中就提前申明name属性,在针对多个实现的情况下。作者今天看到另外一种姿势,主要是通过BeanFactory接口以及ApplicationContextInitializer、BeanDefinitionRegistryPostProcessor等接口去实现的。通过这些接口我们可以做更多的扩展,从而避免写name去标记的问题,其次更深化我们对spring的应用吧。

1、首先定义承载对象的接口

代码语言:javascript
复制
public interface Bean {
}

2、定义BeanFactory,实现getObject方法。

代码语言:javascript
复制
public class MyBeanFactoryimplements FactoryBean{


    private String name;


    private String age;


    public String getName() {
        return name;
    }


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


    public String getAge() {
        return age;
    }


    public void setAge(String age) {
        this.age = age;
    }


    public static final Mapmap=new HashMap<>();


    @Override
    public T getObject() throws Exception {
        if (CollectionUtils.isEmpty(map)||!map.containsKey("lele")){
            synchronized (map){
                return (T) execute();
            }
        }else{
            return (T) map.get("lele");
        }
    }


    private Object execute() {
        Mybean mybean = new Mybean(name,age);
        map.put("lele",mybean);
        return mybean;
    }


    @Override
    public Class getObjectType() {
        return null;
    }


    @Override
    public boolean isSingleton() {
        return FactoryBean.super.isSingleton();
    }
}

3、将BeanFactory注入到ioc容器。

代码语言:javascript
复制
public class MyBeanFactoryBean extends MyBeanFactory{

}

Spring注入bean装配厂工具类

代码语言: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);
    }
}

将MyBeanFactory注入到beanDefianition中

代码语言:javascript
复制
@Configuration
public class MyConfig implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        MutablePropertyValues mv=new MutablePropertyValues();
        mv.add("name","jasldf");
        mv.add("age","123");
        MySpringContentUtils.registerBean("jk",MyBeanFactoryBean.class,Mybean.class,mv);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
    }
}

上述中我们要想将MyBeanFactoryBean注入到IOC中,首先我们需要让MySpringContentUtils 拿到ioc,并用静态变量去引用其地址。这时候我们可以采用ApplicationContextInitializer的能力。

代码语言:javascript
复制
public class MyTianApplicationInitlize implements ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        MySpringContentUtils.setContext(configurableApplicationContext);
    }
}

写完代码,我们在resources目录下创建META-INF文件夹,并创建spring.fatories文件,并填入我们的初始化类的路径。具体如图所示。

至此,我们需要的功能就已经写完了。这里我们测试一下。

测试如下;

当然实现上述功能,其实还有其他的方法,这块将spring的多个接口算是整合起来学习一下,换句话说就是写个笔记,用的时候好查一些。

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

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

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

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

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