Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过依赖注入访问Springbean*而不是*_Java_Spring_Dependency Injection - Fatal编程技术网

Java 通过依赖注入访问Springbean*而不是*

Java 通过依赖注入访问Springbean*而不是*,java,spring,dependency-injection,Java,Spring,Dependency Injection,我们有一些域对象是在运行时创建的,而不是由Spring创建的。这些域对象需要访问由Spring管理的某些服务类型bean。在运行时创建的域对象如何动态地(而不是通过DI)访问Springbean?您必须给他们一个对ApplicationContext或BeanFactory的引用,这样他们才能获得Spring管理的bean。您可以使用@duffymo建议的方法,但如果您不是以web应用程序的形式运行Spring,那么您应该这样考虑。请注意,在最流行的答案中,实用程序类是线程安全的。顺便说一句,O

我们有一些域对象是在运行时创建的,而不是由Spring创建的。这些域对象需要访问由Spring管理的某些服务类型bean。在运行时创建的域对象如何动态地(而不是通过DI)访问Springbean?

您必须给他们一个对ApplicationContext或BeanFactory的引用,这样他们才能获得Spring管理的bean。

您可以使用@duffymo建议的方法,但如果您不是以web应用程序的形式运行Spring,那么您应该这样考虑。请注意,在最流行的答案中,实用程序类是线程安全的。顺便说一句,OP和答案应该是您所需要的,然后您可以使用这个实用程序类来获取对Spring托管bean的引用。

@duffymo的答案是这个问题最常见的解决方案,您可能应该遵循这个解决方案

然而,如果你感觉很粗鲁,如果你的处境支持它,那么你可以考虑用Spring的AspectJ支持来支持春豆:

[…]包含注释驱动的 利用此功能的方面 允许任何 对象该支持旨在: 用于在外部创建的对象 对任何容器的控制。领域 对象通常属于这一类 因为它们经常被创造出来 以编程方式使用新的 运算符,或通过ORM工具作为 数据库查询的结果


它接近伏都教,这种东西,它只在某些应用服务器上工作,但它可能是您的工具。

Spring有一种称为
SingletonBeanFactoryLocator的机制,您可以在一些地方使用,例如EJB2.0应用程序,在不能使用依赖注入的地方获取bean工厂/应用程序上下文。现有Spring
ContextLoader
中有一个钩子,您已经在使用它来利用这个功能,尽管设置起来有些棘手

您需要将应用程序上下文分离为父/子关系。父对象将包含服务层对象,而子对象由特定于web层的内容组成

然后,您必须向web.xml添加几个上下文参数(就像您对配置位置所做的那样),以告诉它初始化父级:

<context-param>
    <param-name>locatorFactorySelector</param-name>
    <param-value>classpath:beanRefFactory.xml</param-value>
</context-param>

<context-param>
    <param-name>parentContextKey</param-name>
    <param-value>beanRefFactory</param-value>
</context-param>
在非死亡域对象中,您可以使用以下代码访问应用程序上下文:

   BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector);
   BeanFactoryReference contextRef= locator.useBeanFactory(parentContextKey);
   ApplicatonContext context = (ApplicationContext) contextRef.getFactory();

您可以在中找到有关
ContextSingletonBeanFactoryLocator
的更多信息。在中关于EJB的一章中也有关于使用这种方法的详细描述。

一种解决方案是使用全局
静态
方法返回Spring应用程序竞赛(请参阅)

其他选项可能是让业务对象实现
ApplicationContextAware
接口。在实例化时,您的“集成”代码必须将Spring
ApplicationContext
注入到动态创建的bean中(可能通过检查类是否实现了
ApplicationContextAware
),这当然会将您的业务代码与Spring绑定,但第一个选项是相同的


一种变体是不直接注入
ApplicationContext
,而是重用Spring
@Autowired
注释。“集成”代码将只注入带注释的字段。

创建工厂并向spring注册,使用工厂创建域对象,而不是使用“新建”

在这种情况下,您的DomainObjFactory提供的所有商品都与此略有关联

您可以采用与Hibernate类似的策略,在域实例工厂中为拦截器创建工具。您可以将所需的服务注入到spring管理的拦截器中,拦截器被注入到您的域工厂中

这将使您的应用程序与特定于Spring的接口分离。下面的例子可以用泛型来简化,但你应该明白这一点

public interface Interceptor {
  public void onCreate(Object entity);
}

public class DomainFactory {
  public void setInterceptors(List<Interceptor> interceptors) { ... }
  public Object createInstance() {
    // iterate interceptors, call onCreate
  }
}

public interface MyServiceAware {
  public void setMyService(MyService service);
}

public class MyServiceInjector implements Interceptor {
  private MyService myService;
  public void onCreate(Object entity) {
    if (entity instanceof MyServiceAware)
      ((MyServiceAware) entity).setMyService(myService);
  }
}
公共接口拦截器{
创建时公共作废(对象实体);
}
公共类域工厂{
公共无效集拦截器(列表拦截器){…}
公共对象createInstance(){
//迭代拦截器,调用onCreate
}
}
公共接口MyServiceAware{
public void setMyService(MyService服务);
}
公共类MyServiceInjector实现拦截器{
私人MyService-MyService;
创建公共void(对象实体){
if(myServiceWare的实体实例)
((myserviceware)实体).setMyService(myService);
}
}
然后将其配置为

<bean id="myServiceInjector" class="MyServiceInjector">
  <property name="myService" ref="someServiceBean" />
</bean>

<bean class="DomainFactory">
  <property name="interceptors">
    <list>
      <ref bean="myServiceInjector"/>
    </list>
  </property>
</bean>

您可以使用非Spring托管域对象可以使用的静态getInstance()方法将依赖对象设置为单例。然后,您可以通过org.springframework.beans.factory.config.MethodInvokingFactoryBean将其提供给Spring,如下所示:

<bean id="myObject"
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="staticMethod">
        <value>com.example.MyObject.getInstance</value>
    </property>
</bean>

com.example.MyObject.getInstance

在web应用程序中执行此操作的最佳实践是什么?动态创建的域对象需要以这种方式访问SpringBean是否常见?我建议查看WebApplicationContextUtils:。我认为让Spring管理豆子更为常见。只有方法调用上下文中的本地bean才会使用“new”创建。
<bean id="myObject"
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="staticMethod">
        <value>com.example.MyObject.getInstance</value>
    </property>
</bean>