Spring bean partial autowire prototype constructor

2019-09-11 14:33发布

I have a class:

@Slf4j
@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class WebSocketRegistrar extends AbstractWebSocketHandler{


    private final ApplicationContext context;



    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // problem here.
        context.getBean(WebSocketConsumer.class, session);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {

    }

}

and it attempts to create a prototype bean where 1 of the parameters is a runtime argument and the rest I want injected. I need it to take the EventBus and a function. Both are available in the context and I can work past this problem. I am trying to understand how I can do partial constructor autowiring on a prototype

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@NoArgsConstructor
public class WebSocketConsumer implements Consumer<Identifiable<?>> {

    private WebSocketSession session;

    private Function<Identifiable<?>, String> jsonApi;

    @Autowired
    public WebSocketConsumer(WebSocketSession session, EventBus bus, BiFunction<Identifiable<?>, String, String> toJsonApi) {
        this.session = session;
        this.jsonApi = identifiable -> toJsonApi.apply(identifiable,session.getHandshakeHeaders().get("Host").get(0));
        bus.on(R(session.getUri().getPath() + "/?.*"),this::accept);

    }


    @Override
    public void accept(Identifiable<?> update) {

    }

}

标签: java spring
1条回答
聊天终结者
2楼-- · 2019-09-11 15:32

I think you might need to rephrase your question, either ask a bout a very minimal example of what you want to achieve in Spring, or just ask about the pure Spring DI problem you are having. But anyway on the Spring Dependency Injection side it sounds like what you need is a Configuration, which you can create beans from:

@Configuration
public class TestConfiguration {

    @Bean
    @Autowired
    @Scope("prototype")
     public SomePrototypeBean createBean(SingletonBean singletonBean){
          return new SomePrototypeBean(singletonBean, "TODO whatever you want here" );
     }
}

This way you have greater control over the constructor arguments going into your bean, and can put in singleton beans in the constructor, and some sort of argument which changes at run-time, I left it as TODO. At all costs avoid context.getBean. If you find yourself doing these sorts of things you may need to rethink about the way you are trying to achieve something. It should only be used to overcome a limitation of the framework, if any other solution exists it is preferable.

查看更多
登录 后发表回答