我有一些可以通过标识符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
。
是否可以实施?
答案 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。