用另一个bean包裹spring bean

时间:2014-04-17 16:44:21

标签: java spring

我有一些可以通过标识符someSpecificService访问的服务bean,我需要修改它。 Bean在不同的xml文件中定义,并在运行时一起收集。因此创建了一个大的xml文件,其中导入了所有这些xml:

context.xml
....
<import path="spring1.xml" />
<import path="spring2.xml" />
...

所以有以下配置:

<-- definitions from spring1.xml -->
<alias name="defaultSomeSpecificService" alias="someSpecificService" />
<bean id="defaultSomeSpecificService" class="..."/>
....
<!-- definitions from spring2.xml -->
<alias name="myOwnSomeSpecificService" alias="someSpecificService" />
<bean id="myOwnSomeSpecificService" class="..." /> <!-- how to inject previously defined someSpecificService into this new bean? -->

我想在someSpecificService中覆盖spring1.xml中的spring2.xml,但我确实需要注入以前定义的bean defaultSomeSpecificService,而我所知道的只是它的别名someSpecificService 1}}我需要重新定义到新的bean myOwnSomeSpecificService

是否可以实施?

1 个答案:

答案 0 :(得分:2)

一种解决方案是避免尝试通过creating a proxy for the service implementation to intercept all calls覆盖定义。

1)为了举例,假设服务类似于:

public interface Service {
    public String run();
}

public class ExistingServiceImpl implements Service {

    @Override
    public String run() {
        throw new IllegalStateException("Muahahahaha!");
    }
}

2)实现拦截器而不是myOwnSomeSpecificService

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class SomeSpecificServiceInterceptor implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        String status;
        try {
            // allow the original invocation to actually execute
            status = String.valueOf(invocation.proceed());
        } catch (IllegalStateException e) {
            System.out.println("Existing service threw the following exception [" + e.getMessage() + "]");
            status = "FAIL";
        }
        return status;
    }
}

3)在spring2.xml中定义代理创建者和拦截器:

<bean id="serviceInterceptor" class="com.nsn.SomeSpecificServiceInterceptor" />

<bean id="proxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
    <property name="beanNames" value="someSpecificService"/>
    <property name="interceptorNames">
        <list>
            <value>serviceInterceptor</value>
        </list>
    </property>
</bean>

4)运行一个小例子,例如:

public class Main {
    public static void main(String[] args) {
        Service service = new ClassPathXmlApplicationContext("context.xml").getBean("someSpecificService", Service.class);
        System.out.println("Service execution status [" + service.run() + "]");
    }
}

...而不是您通常期望的IllegalStateException堆栈跟踪,它将打印出来:

Existing service threw the following exception [Muahahahaha!]
Service execution status [FAIL]

请注意,在此示例中,服务实例未按要求注入拦截器,因为我没有用户。但是,如果你真的需要它,你可以通过constructor / property / etc轻松注入它,因为拦截器本身就是一个spring bean。