首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何进行iPOJO实例化

如何进行iPOJO实例化
EN

Stack Overflow用户
提问于 2014-04-03 19:56:03
回答 1查看 791关注 0票数 3

我在理解iPOJO中的组件实例化概念时遇到了一些问题。我读过本指南,我理解了类和对象的类推,但是我仍然有一些具体的问题和一些概念性的问题,我希望有人能澄清。

我认为我需要通过iPOJO (@实例化或工厂)为服务提供者创建只用于的实例,因为它们从不使用新的,因为impl总是隐藏的。但是,我有一些使用者@组件是我自己实例化的(比如在main()方法中,我直接对它们调用了new )。我制作了它们的“组件”,因为它们需要注入一些东西。我假设ipojo字节码操作会使其成为这样,以便在构造对象时注入它们的依赖项(我主要是使用@Bind的方法注入),但情况似乎并非如此。有人能跟我澄清一下吗。现在,在我看来,对于iPOJO来说,要执行任何注入,都需要始终使用iPOJO实例化技术之一。我遇到的问题是,我在使用者类中创建的构造函数不会被调用。

这是一个简单的例子来说明我的困惑。

代码语言:javascript
复制
@Component(name="test")
public class MyFoo {
    private List<External> externals; //injected
    private Bar bar; //passed via constructor. Bar is *not* a @Component

    public MyFoo(Bar otherBar) {
        bar = otherBar;
        externals = new ArrayList();
    }

    @Bind(aggregate=true)
    public addExternal(External service) {
        externals.add(service);
    }
}

因此,正如这里所看到的,我需要有接口External的所有提供者,但我也需要一个Bar对象,当我使用new MyFoo(someBar)构造对象时,需要传递这个对象。

我的问题是,如果我需要将一个Bar传递给构造函数,那么我需要使用new;但是如果我使用new,iPojo就不会调用我的注入方法。另一方面,如果我使用iPOJO实例化(比如我添加@实例化),那么注入就会发生,但是构造函数不会被调用,因此绑定抛出一个NPE,因为列表还没有创建,+ bar将不会被设置。我知道我可以在bind方法中创建列表,但我的问题更具有概念性。

  1. 您应该如何完成这一任务(框架注入+在构造函数中传递参数)?
  2. iPOJO如何在不调用创建对象的唯一构造函数的情况下调用addExternal (这意味着已经创建了对象)?这在标准java中是非常违反直觉的。
  3. 您只是在使用iPOJO组件时不应该使用构造函数吗?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-04-07 21:44:19

iPojo的工作方式类似于其他DI (依赖注入)框架,如Blueprint (OSGi)、Spring、Guice等。也就是说,为了让DI完成它的工作,您必须让容器(iPojo)管理与您交互的对象的生命周期。因此,您的倾向是正确的:您必须使用iPojo的实例化技术之一。如果您选择在对象上使用新的,那么您的代码将管理生命周期(因此您将需要手动“注入”所有参数)。

在本例中,您的构造函数不会被调用,因为开箱即用的iPojo将支持两种主要情况:默认构造函数(MyFoo())或接受BundleContext (MyFoo(BundleContext c))的构造函数。iPojo还支持构造函数服务和属性注入,如果您在1.7.0版或更高版本上分别对构造函数变量(或元数据中的等价物)使用@Requires / @Property

当iPojo 字节码操作启动时,它操作字节码,使其由iPojo来管理,而不是由iPojo管理。它通过添加MyClass(InstanceManager)构造函数以及iPojo在实例化对象时在内部使用的其他方法来实现这一点。

所以,回答你的问题:

  1. 您可以通过将注入变量定义为属性或服务需求并委托iPojo来创建它们来实现这一点。iPojo有用于与实例创建交互的多种方法,但是您可能感兴趣的两个是通过OSGi ConfigurationAdmin或iPojo工厂(假设publicFactory在@Component上设置为true,这是默认的)。例如,使用配置管理和假设Bar不存在于OSGi服务注册表中,您的MyFoo类如下所示: @Component(name="test")公共类MyFoo {私有列表外部;//注入私有条形条;//通过构造函数传递。bar为*非*a @Component public MyFoo(@Property(name = "somebar") Bar otherBar) { Bar = otherBar;externals =新的ArrayList();} @Bind(aggregate=true)公共addExternal(外部服务){externals.add(服务);} 然后,使用configuration (或iPojo工厂)创建一个实例。因此,您的主要方法将从ConfigAdmin服务层中提取iPojo或iPojo工厂(例如,从BundleContext中取出它,等等),创建一个配置,将"somebar“属性设置为"new ()”,并保存该配置。然后为您创建的iPojo托管服务工厂将使用您在配置中提供的新条实例化MyFoo的一个版本,并将其注入MyFoo构造函数: ..。Configuration config = configAdmin.createFactoryConfiguration( MyFoo.class.getCanonicalName());Hashtable properties =新Hashtable<>();properties.put("somebar",new ());//这是您新的config.update(属性)的位置;//如果您需要更新//实例或以后销毁它,那么对配置做一些有用的事情。..。 配置管理员的createFactoryConfiguration的第一个参数指定pid。在本例中,pid是类的名称,除非在iPojo注释中覆盖它,否则默认情况下将使用pid。然后,将您的某个条添加到属性中,并更新配置。iPojo工厂与此类似,不过我认为它使用构建器模式来创建实例。如果不想添加对iPojo配置管理的依赖,最好使用OSGi工厂。
  2. 我不是iPojo内部程序的专家,我在这里根据我的经历和在他们的文档中所读到的内容得出了一个结论。如前所述,iPojo通过字节码操作来增强类,使其可由iPojo管理。它为类添加的一个特征是具有InstanceManager的构造函数。由于您添加的构造函数没有绑定到它的元数据(即注释--我假设清单或xml文件中没有手动元数据),它或多或少完全忽略了该构造函数,而是选择使用字节码操作过程动态生成的构造函数。一旦完成,它最终将调用您的@Bind方法来添加外部服务(因为该方法已被标记),您将发现自己处于您所描述的状态。
  3. 这里的关键是让iPojo管理对象的生命周期,如前所述。通过调用构造函数,您实际上是在管理该实例的生命周期,因此iPojo不在循环中。因此,您可以使用构造函数并手动向其“注入”参数,也可以依赖iPojo为您执行此操作。
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22847701

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档