加入收藏 | 设为首页 | 会员中心 | 我要投稿 汽车网 (https://www.0577qiche.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

JavaSE实现IoC

发布时间:2023-04-18 14:21:13 所属栏目:教程 来源:
导读:简单地说,IoC 是反转控制,类似于好莱坞原则,主要有依赖查找和依赖注入实现

依赖查找是主动或手动的依赖查找方式,通常需要依赖容器或标准API实现。 而依赖注入则是手动或自动依赖绑定的方式,无需依赖特定的容
简单地说,IoC 是反转控制,类似于好莱坞原则,主要有依赖查找和依赖注入实现

依赖查找是主动或手动的依赖查找方式,通常需要依赖容器或标准API实现。 而依赖注入则是手动或自动依赖绑定的方式,无需依赖特定的容器和API

JavaSE中的IoC实现方式
Java SE 提供了三种方式,可以实现IoC,分别为:

Java Beans
Java ServiceLoader SPI
JNDI(Java Naming and Directory Interface)
Java Beans
java.beans包下的 Introspector 类提供了一个 getBeanInfo的方法,可以获取一个类的信息

BeanInfo bi = Introspector.getBeanInfo(User.class,Object.class);
如上,则可以获取User类对象的BeanInfo, 然后我们通过BeanInfo中的 getPropertyDescriptors 方法,可以获取到User对象中的所有属性和方法,

注意:java beans中,对于set(xxx)方法,统一叫:writeMethod(), 对于get() 方法,统一叫:readMethod()

Stream.of(bi.getPropertyDescriptors()).forEach(pd->{
        Class<?> propertyType=pd.getPropertyType();
        Method writeMethod=pd.getWriteMethod();
        });
获取到方法和属性名称后,通过反射即可把对应的值设置到对应的属性中

writeMethod.invoke(name,value);
由于我们注入属性值的时候,我们注入的东西永远是一个字符串类型,如果需要注入的属性是其他类型(非字符串), 比如User类中,有一个属性是address,这个address是一个对象类型,我们应该如何定义一个转换器,将字符串类型的值转换为我们需要的对象类型呢?

我们需要通过设置一个AddressEditor来实现这个转换,这个AddressEditor有如下两种实现方式:

实现propertyeditor接口

继承propertyeditorSupport类,重写setAsText方法

propertyeditorSupport类提供了一些比较便利的实现方式,所以我们采用继承propertyeditorSupport类的方法,来实现类型的转换,

Address类的设计是:

public class Address {
    private String name;
    private Integer num;
    // 省略 get / set / toString
}
我们的定义的规则如下,

输入的字符串用|来分割 name 和 num属性

例如: “贝克街|221” 这个字符串 会将“贝克街”赋给name,221赋给num,所以,我们重写setAsText方法的逻辑如下:

public class AddressEditor extends propertyeditorSupport {
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        String[] tokens = text.split("\\|");
        Address address = new Address();
        address.setName(tokens[0]);
        address.setNum(Integer.valueOf(tokens[1]));
        setValue(address);
    }
}
同理,我们可以实现一个DateEditor,让“yyyy-MM-dd”这样类型的字符串转换成日期格式。

public class DateEditor extends propertyeditorSupport {
    static final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        LocalDate localDate = LocalDate.parse(text, dtf);
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
        setValue(Date.from(instant));
    }
}

(编辑:汽车网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章