我在理解iPOJO中的组件实例化概念时遇到了一些问题。我读过本指南,我理解了类和对象的类推,但是我仍然有一些具体的问题和一些概念性的问题,我希望有人能澄清。
我认为我需要通过iPOJO (@实例化或工厂)为服务提供者创建只用于的实例,因为它们从不使用新的,因为impl总是隐藏的。但是,我有一些使用者@组件是我自己实例化的(比如在main()方法中,我直接对它们调用了new )。我制作了它们的“组件”,因为它们需要注入一些东西。我假设ipojo字节码操作会使其成为这样,以便在构造对象时注入它们的依赖项(我主要是使用@Bind的方法注入),但情况似乎并非如此。有人能跟我澄清一下吗。现在,在我看来,对于iPOJO来说,要执行任何注入,都需要始终使用iPOJO实例化技术之一。我遇到的问题是,我在使用者类中创建的构造函数不会被调用。
这是一个简单的例子来说明我的困惑。
@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方法中创建列表,但我的问题更具有概念性。
发布于 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在实例化对象时在内部使用的其他方法来实现这一点。
所以,回答你的问题:
@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工厂。InstanceManager的构造函数。由于您添加的构造函数没有绑定到它的元数据(即注释--我假设清单或xml文件中没有手动元数据),它或多或少完全忽略了该构造函数,而是选择使用字节码操作过程动态生成的构造函数。一旦完成,它最终将调用您的@Bind方法来添加外部服务(因为该方法已被标记),您将发现自己处于您所描述的状态。https://stackoverflow.com/questions/22847701
复制相似问题