如何向Spring未管理的Jar包抽象类A注入Type B依赖?
Hey there! Since your abstract class A from the external JAR isn't managed by Spring, we can't use Spring's automatic injection directly on it. But don't worry—we've got a few straightforward ways to get your custom B bean into A. Let's walk through them:
1. Constructor Injection (Recommended)
This is the cleanest approach, following dependency injection principles. Since you can't instantiate an abstract class directly, create a subclass of A with a constructor that accepts B, then pass the Spring-managed B bean when creating the subclass instance.
First, your existing @Configuration class already defines the B bean:
@Configuration public class BeanConfig { @Bean public B getB() { return new MyB(); } }
Then, create a subclass of A and use constructor injection to pass B:
// Your custom subclass of A public class MyA extends A { private final B b; public MyA(B b) { this.b = b; // If A has a protected method to set its dependency, use it here // super.setDependency(b); } // Implement any abstract methods from A, using the injected B as needed }
Now, in any Spring-managed component where you need A, inject B and create your MyA instance:
@Component public class MyBusinessService { private final A aInstance; // Inject the Spring-managed B bean via constructor public MyBusinessService(B b) { this.aInstance = new MyA(b); } // Use aInstance in your business logic }
2. Setter Injection
If A provides a setter method for its dependency (or you can add one in your subclass), you can inject B after creating the A instance:
@Component public class MyBusinessService { private final A aInstance; public MyBusinessService(B b) { this.aInstance = new MyA(); // Call the setter to pass the Spring-managed B aInstance.setB(b); } }
3. Make A's Subclass a Spring-Managed Bean
If you want Spring to handle the lifecycle of A's instance entirely, mark your subclass as a Spring component and inject B directly into it:
@Component // This tells Spring to manage this class public class MyA extends A { private final B b; // Spring 4.3+ doesn't require @Autowired for constructor injection public MyA(B b) { this.b = b; // Pass B to parent A if needed } }
Now you can inject A directly into any Spring component—Spring will automatically provide the MyA instance with B already injected:
@Component public class MyBusinessService { private final A aInstance; public MyBusinessService(A aInstance) { this.aInstance = aInstance; } }
4. Wrap A's Factory Method (If A is Created by the JAR)
If the JAR provides a factory method to create instances of A, wrap that factory method in a Spring @Bean definition to inject B:
@Configuration public class AConfig { @Bean public A getA(B b) { // Use the JAR's factory method to get an A instance A a = ExternalAFactory.createA(); // Inject B into A using its setter or any available method a.setB(b); return a; } }
Now A becomes a Spring-managed bean, and you can inject it anywhere in your app just like any other bean.
The key takeaway is: since A isn't in Spring's context, we either manually pass the managed B to A's instance, or bring A (or its subclass) into Spring's context so it can handle the injection for us.
内容的提问来源于stack exchange,提问作者User3518958

