Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.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定义,但仍然引用被重写的bean?_Java_Spring - Fatal编程技术网

Java 如何重写Springbean定义,但仍然引用被重写的bean?

Java 如何重写Springbean定义,但仍然引用被重写的bean?,java,spring,Java,Spring,我试图通过用我的委托服务覆盖原始服务的bean定义来实现委托服务提供者。但是,顾名思义,委托服务需要一个对原始服务的引用来委托调用 在使用原始bean def时,我很难理解如何重写bean定义,而不会遇到循环引用问题 例如: <!-- Original service def in spring-context.xml --> <bean id="service" class="com.mycompany.Service"/> <!-- Overridden de

我试图通过用我的委托服务覆盖原始服务的bean定义来实现委托服务提供者。但是,顾名思义,委托服务需要一个对原始服务的引用来委托调用

在使用原始bean def时,我很难理解如何重写bean定义,而不会遇到循环引用问题

例如:

<!-- Original service def in spring-context.xml -->
<bean id="service" class="com.mycompany.Service"/>

<!-- Overridden definition in spring-plugin-context.xml -->
<bean id="service" class="com.mycompany.DelegatedService"/>
    <constructor-arg ref="service"/>
</bean>

这可能吗?

您可以创建。因此,现在名为
service
的bean将成为原始
服务的代理,该服务需要重命名为其他服务。因此,这些更改将仅限于SpringXML,而不会传播到java代码中

<bean id="personTarget" class="com.mycompany.PersonImpl">
    <property name="name"><value>Tony</value></property>
    <property name="age"><value>51</value></property>
</bean>

<bean id="myAdvisor" class="com.mycompany.MyAdvisor">
    <property name="someProperty"><value>Custom string property value</value></property>
</bean>

<bean id="debugInterceptor" class="org.springframework.aop.interceptor.DebugInterceptor">
</bean>

<bean id="person" 
    class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="proxyInterfaces"><value>com.mycompany.Person</value></property>

    <property name="target"><ref local="personTarget"/></property>
    <property name="interceptorNames">
        <list>
            <value>myAdvisor</value>
            <value>debugInterceptor</value>
        </list>
    </property>
</bean>

托尼
51
自定义字符串属性值
com.mycompany.Person
我的顾问
调试拦截器

听起来你在试图重新发明spring AOP。请考虑使用Spring AOP做这个。< /P> 可以通过编程更改现有服务的名称,并使用旧名称创建一个新bean。spring框架中的自动代理代码实现了这一点,您可以看看这一点。在spring框架中对AutoProxy*进行快速代码搜索应该可以达到目的

或者,如果控制客户机站点(消费者),则可以向包装器添加限定符,并使用限定符强制消费者正确实现。包装器可以使用不合格的实现来访问原始实现。
(也可以通过在xml代码中为服务添加另一个bean定义,并使用您控制的限定符将限定符重新装载到原始实现中,您还没有尝试过,但它应该可以工作)

您的问题的简短答案是,您不能有两个同名的bean定义。如果尝试,一个将隐藏另一个,并且只有一个定义可用

您的问题的示例似乎表明您正在尝试将原始的
服务
bean包装在代理对象中,包装器执行对服务的一些前后处理调用。实现这一点的一种方法是使用Spring
AutoProxyCreator
,它可能是一个

这允许您列出要自动代理的bean。指定要应用于目标bean上的调用的拦截器。您将实现这些拦截器来完成您需要完成的工作

Spring将自动为您创建一个委托代理,该代理与以前一样具有bean id
服务
,但具有您的附加功能。

将“ref”元素的“parent”属性与父容器一起使用。

您可以在Spring文档中找到一个详细的示例:

已经写了一篇关于如何很好地做到这一点的博客文章:

使用通配符上下文定义意味着您不需要使用导入


当您想用相同的id重新定义同一个bean时,Parent不起作用。

我不能将原始的“服务”bean重命名为其他任何东西,因为它是在spring上下文中定义的,这在我的控制范围之外,在spring中是不可能的。此外,即使有可能,这也是一种不好的做法,如果有人在编写bean时考虑到了特定的功能,并关闭它进行修改,那么最终可能会破坏原有的功能。一个(不好的)解决方法是使用相同的签名定义自己的类,并使用自定义类装入器加载原始类并委托给它。如果你能发布你的最终要求会更好。这个答案是最有用的,尽管我的问题最终无法解决。为了代理该类,它必须由方面编织。因为我试图代理的类已经在另一个类加载器中编译和运行,所以我无法代理它。@Kevin:An
AutoProxyCreator
不代理类,它代理bean。哪个类加载器加载目标类并不重要,代理的是目标对象,Spring实例化了该目标对象。在一个配置中,将其别名为目标bean名称,在另一个配置中,定义注入底层bean的包装器。但这需要事先计划。