LJiangTao opened a new issue, #13508:
URL: https://github.com/apache/dubbo/issues/13508
# Scenario
We need to call a remote service in Filter to get the address of the service
that load balance can call later.
# Solution
```java
@Activate(group = { CommonConstants.CONSUMER })
public class DeviceSelectorFilter implements Filter {
public DeviceSelectorFilter(ApplicationModel model) {
// Get Extension that contain Spring Application Context.
SpringExtensionInjector springExtensionInjector =
SpringExtensionInjector.get(
model
);
// Now you get Spring Application Context.
var applicationContext = springExtensionInjector.getContext();
}
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation)
throws RpcException {
// YOUR BUSNIESS LOGIC
}
}
```
> I use JDK-17, If you are using JDK-1.8.0, replace [var] to target class.
## Constructor Instantiates
The Dubbo framework instantiates the filter itself, therefore interfaces
related to Spring (such as BeanFactoryAware) are not supported. However, Dubbo
provides injectable objects that must implement ScopeModel. such as :
- `org.apache.dubbo.rpc.model.ApplicationModel`
- `org.apache.dubbo.rpc.model.FrameworkModel`
- `org.apache.dubbo.rpc.model.ModuleModel`
Other types do not support constructor injection. more details in
`org.apache.dubbo.common.beans.support.InstantiationStrategy` Class.
```java
@SuppressWarnings("unchecked")
public <T> T instantiate(Class<T> type) throws ReflectiveOperationException {
// HIDE SOME CODE.
// 2. use matched constructor if found
List<Constructor<?>> matchedConstructors = new ArrayList<>();
Constructor<?>[] declaredConstructors = type.getConstructors();
for (Constructor<?> constructor : declaredConstructors) {
// HERE! CHECK Constrcutor Arguments Object must implement
ScopeModel!!!
if (isMatched(constructor)) {
matchedConstructors.add(constructor);
}
}
// HIDE SOME CODE
// create instance with arguments
Class<?>[] parameterTypes = targetConstructor.getParameterTypes();
Object[] args = new Object[parameterTypes.length];
for (int i = 0; i < parameterTypes.length; i++) {
// get target scopeModel object.
args[i] = getArgumentValueForType(parameterTypes[i]);
}
return (T) targetConstructor.newInstance(args);
}
private boolean isMatched(Constructor<?> constructor) {
for (Class<?> parameterType : constructor.getParameterTypes()) {
if (!isSupportedConstructorParameterType(parameterType)) {
return false;
}
}
return true;
}
private boolean isSupportedConstructorParameterType(Class<?> parameterType) {
return ScopeModel.class.isAssignableFrom(parameterType);
}
}
```
## Try Get `BeanFactory` by `ApplicationModel`
`ApplicationModel` has `getBeanFactory()` method. but it return
`ScopeBeanFactory` , that is internal BeanFactory of Dubbo, not Spring
BeanFactory. `ScopeBeanFactory` contains only objects instantiated by dubbo
itself, not objects from the spring `BeanFactory`.
<b> THIS WAY IS DEAD END </b>
- `org.apache.dubbo.rpc.model.ScopeModel`
```java
public abstract class ScopeModel implements ExtensionAccessor {
private volatile ScopeBeanFactory beanFactory;
public ScopeBeanFactory getBeanFactory() {
return beanFactory;
}
}
```
# Thanks
Very thankful of Dubbo Community's `Liu Jun`, Thanks !
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]