Yang Chen
Yang Chen

Reputation: 55

Create proxy for a interface, which could inject by @Autowired, proxy invokes different implement by key parameter

I want to define a annotation like @PlatformRelated, once it is marked in a interface, there will be a proxy bean at spring context, and this proxy bean should be @Priority.I want this proxy could invoke different implement according to key parameter @KeyPrameter.And I still wanna use spring features like @Async,@Trasaction,etc... at my Implement1 and Implement2.

@PlatformRelated
interface MyInterface {
   method(@KeyPrameter String parameter);
}

@Component
class Implement1 implements MyInterface {
   method(String parameter){
       //do something 111
   }
}

@Component
class Implement2 implements MyInterface {
   method(String parameter){
       //do something  222
   }
}

@Service
class BusinessService{
    @Autowired
    private MyInterface myInterface;

    public void doSomething() {
        myInterface.method("key1");
        //Implement1 work
        myInterface.method("key2");
        //Implement2 work
    }
}

Do you guys have some good idea to complete it?

Upvotes: 0

Views: 806

Answers (1)

Mark Bramnik
Mark Bramnik

Reputation: 42511

I must admit I haven't totally understood the meaning @Priority, however, I can say that if you want to implement this feature in spring, you should probably take a look at Bean Post Processors.

BeanPostProcessors are essentially a hook to Bean Creation process in spring intended for altering bean behavior. Among other things, they allow wrapping the underlying bean into the proxy (CGLIB/java.lang.Proxy if you're working with interfaces, or even using programmatically Spring AOP), these proxies can provide a hook to the method execution that can read your annotations (like mentioned @KeyParameter) and execute a code in a way similar to Aspect's code that you already make use of.

Not all bean post processor wrap the bean into the proxy. For example, if you want to implement a BPP that uses "@Autowire", you will return the same bean, just "inject" (read, put by reflection) its dependencies. On the other hand, if you want to implement with BPP @Transactional behavior, then yes, you should wrap the bean into a proxy that would take care of transaction management capabilities before and after the method execution.

It's totally ok to have a spring bean that gets "altered" by many post processors, some of them would wrap it into a proxy other will just modify-and-return the same bean, If there are many BPP-s that wrap the bean into proxy we'll get "proxy inside proxy inside proxy" (you get the idea). Each layer of proxy will handle one specific behavior.

As an example, I suggest you take a look at existing Spring postprocessors, or, for instance, a source code of the following library: Spring Boot metering integration library

This library contains some implementations of post processors that allow metrics infrastructure integration by defining annotations on methods of Spring Beans.

Upvotes: 1

Related Questions