zoukankan      html  css  js  c++  java
  • java 枚举类如何获取spring管理的Bean对象

    1.情景展示

      像枚举类中注入spring管理的bean对象虽然不常见,但是,也有它对应的使用场景,如何实现?

    2.原因分析

      以springboot为例,可像普通类那样通过注解@Autowire或@Resource注入对象。

      如上图所示,在枚举类中也是可以使用@Resource或@Autowired注入对象,一开始我以为不可以,后来发现其实也是可以哒;

      只不过,平常我们在类中注入对象是写在类的最前面(作为类的私有属性),而在枚举中,需遵循:枚举对象在最上面,私有属性在下面;

      这就会出现一个问题,因为枚举类在最上面,而注入的对象在下面(代码先后顺序问题),所以,我们无法在添加枚举类的时候,就为属性interfaceType赋值;

      这就很尴尬,不过好在有注解@PostConstruct,被该注解声明的方法,会在注解@Resource或@Autowired执行后,再执行;

      这样一来,我们就可以在PostContruct()方法中拿到注入的bean对象,进而就可以为指定的枚举类重新为其属性interfaceType进行赋值;

      这样,就实现了:为不同的接口注入不同的业务实现类,也就是不同接口可以自动调用各自的业务处理类。

      但是,在实际测试中发现,注入的bean对象还是为空。

    3.解决方案

    // @Setter不支持直接声明在枚举类上
    @Getter
    @AllArgsConstructor
    public enum CzInterfaceEnum {
        // 下面有枚举类的构造方法
        INTERFACE_CZ5101("cz5101");
    
        @JsonValue
        private String interfaceName;
    
        // 接口类型
        @Setter
        private InterfaceCz interfaceType;
    
        /**
         * 为枚举类注入spring管理的bean对象
         * @description:
         * @attention: 对象的注入必须创建一个单独的类来完成,不然注入的对象都是null
         * @author: Marydon
         * @date: 2020年10月29日 0029 17:47
         * @version: 1.0
         * @email: marydon20170307@163.com
         */
        @Component
        public static class EnumTypeServiceInjector {
            // 为该类注入对象
            @Resource private InterfaceCz cz5101Impl;
            /*
             * 将注入的对象添加到对应的枚举类中
             * @attention:
             * @date: 2020年11月13日 0013 19:02
             * @param:
             * @return: void
             */
            // @Autowired, @Resource执行后会走该注解
            @PostConstruct
            private void postConstruct() {
                INTERFACE_CZ5101.setInterfaceType(cz5101Impl);
            }
        }
    
        /*
         * 创建只有一个参数的构造方法
         * @explain: 创建枚举类(只给一个属性赋值)
         * 另一个属性通过EnumTypeServiceInjector注入对象并赋值
         * @attention:
         * @date: 2020年11月13日19:13:01
         * @param: interfaceName 接口名称
         * @return:
         */
        CzInterfaceEnum(String interfaceName) {
            this.interfaceName = interfaceName;
        }
    }
    

      这样,当我们使用枚举的时候,就能获得它所注入的对象。

      说明:

      通过@Autowire或@Resource注入的对象,支持开启多线程异步访问

      使用场景,见文末推荐。

    写在最后

      哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!

     相关推荐:

  • 相关阅读:
    EntityFramework+MySql 笔记2
    EntityFramework+MySql 笔记1
    软件详细设计文档(终)
    软件测试文档(终)
    软件测试计划文档(初)
    软件概要设计文档(终)
    软件需求规格说明文档(终)
    例会记录(六)
    例会记录(五)
    例会记录(四)
  • 原文地址:https://www.cnblogs.com/Marydon20170307/p/14311832.html
Copyright © 2011-2022 走看看