Make a member of a bean available for autowiring

@org.springframework.beans.factory.annotation.autowired(required=true) in spring boot
default autowiring in spring
spring autowire multiple beans of same type
how to autowire parameterized constructor in spring boot
spring @autowired annotation example without xml
why we use autowiring in spring
autowiring in spring example byname
autowired(required = false)
@Component
class MultiProvider {
    public Foo getFoo();
    public Bar getBar();
}

@Component
class FooConsumer {
    FooConsumer(Foo f);
}

Can I have MultiProvider.getFoo() autowired into the FooConsumer constructor..

  • without making Foo a bean itself (for example, because Spring should not destroy it, since that is MultiProviders responsibility)
  • and without introducing a dependency from FooConsumer to MultiProvider (or any other class)?

You can achieve this simply by annotating getFoo() method in MultiProvider by @Bean

@Component
class MultiProvider {
    @Bean(destroyMethodName="cleanup")      // HERE IS THE TRICK
    public Foo getFoo();
    public Bar getBar();
}

@Component
class FooConsumer {
    FooConsumer(Foo f);
}

if the problem comes from the point that spring can not properly destroy it you can include the logic inside cleanup method declared while annotating by @Bean

public class Foo {
    public void cleanup() {
        // destruction logic
    }
}    

Note that @component and @configurable are more or less the same with some subtle differences but in your case you can use @component if you don't want to change it. More Info

Spring Autowire Example, can't be used to inject primitive and string values. It works with reference only. Apart from the autowiring modes provided in bean configuration file, autowiring can be specified in bean classes also using @Autowired annotation. To use @Autowired annotation in bean classes, you must first enable the annotation in spring application using below configuration. 2.1. Enable annotation config <context:annotation-config />

Spring can only autowire declared beans, a possible workaround can be something like the following:

@Component
class FooConsumer {
    private final Foo foo;

    FooConsumer(MultiProvider multiProvider) {
        // MultiProvider will be autowired by spring - constructor injection
        this.foo = multiProvider.getFoo();
    }
}

Autowiring in Spring, A guide to the most commonest usage of Springs @Autowired annotation to enable autowiring, various ways to wire in beans, making beans optional, Spring expects @Autowired dependencies to be available when the  Autowiring Modes. Following are the autowiring modes, which can be used to instruct the Spring container to use autowiring for dependency injection. You use the autowire attribute of the <bean/> element to specify autowire mode for a bean definition.

You can include them in your Configuration.

@Configuration
class MyConfig {
    @Bean
    public MultiProvider getMP() {
        return new MultiProvider() ;
   }
   @Bean
   public Foo getFoo() {
        return getMP(). getFoo();
   } 
}

Not sure if that violates your 'not a Bean itself' rule.

Spring autowire interface, Let's check out how to do this using the XML-based autowiring functionality. indicating that more than one bean is available for autowiring. If more than one beans of the same type are available in the container, the framework will throw a fatal exception indicating that more than one bean is available for autowiring. 5.1. Autowiring by @Qualifier

Spring Couldn't autowired,there is more than one bean of `` type , For example, in our case, we were trying to get the EntityManager bean inside FileEntityListener. We can simply do that by writing BeanUtil. byName : Spring container looks for bean name same as property name of the class for autowiring. byType : Spring container selects the bean by class type for autowiring. constructor : Spring container uses constructor based autowiring. no : No Autowiring. Use ref attribute to resolve dependency. default : The default autowiring is "no". Default autowiring will inherit parent bean autowiring if nested.

Guide to Spring @Autowired, The spring bean autowiring functionality has four modes. You have to explicitly set the dependencies using <property> tags in bean It totally exclude that specific bean definition from being available to the autowiring infrastructure. autowire byType – For this type of autowiring, class type is used. So there should be only one bean configured for this type in the spring bean configuration file. autowire by constructor – This is almost similar to autowire byType, the only difference is that constructor is used to inject the dependency.

Autowiring in Spring, To enable @Autowired, you have to register '​AutowiredAnnotationBeanPostProcessor', and you can do it in two ways :  3. Auto-Wiring ‘byType’. Autowiring using byType works similarly to byName. When attempting to autowire a property byType, Spring will look T beans whose type is assigned to the property’s type.

Comments
  • why are you using @Bean on the class ? @ Bean is a method level annotation docs.spring.io/spring-javaconfig/docs/1.0.0.M4/reference/html/…
  • @MohammadRezaAlagheband oops, I meant Component
  • what do you mean by this without making Foo a bean itself Autowire will happen only between beans, you can autowire only bean
  • I've reworded my question a bit. I didn't want Spring to destroy Foo because that is MultiProviders responsibility. However, since destroy should be idempotent anyway (in my current opinion at least :P ) I was just being pedantic, and this is how I've solved it indeed (but without the custom destroyMethodName)
  • Yes of course, but my purpose is to not have a dependency from FooConsumer on MultiProvider. I should clarify that
  • That is not possible as far as I know, you can only autowire beans
  • I don't know if its relevant, but you can specify Foo as a bean and add a close() method with your destroy logic so spring will destroy it correctly. Then you can maybe define it as a bean and autowire it - stackoverflow.com/a/44757112/4473822
  • I've reworded the question to expand on the nonbeanrule