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]

Reply via email to