@Override
	public void initialize() {
		List<AbstractEndpoint> endpoints = new ArrayList<AbstractEndpoint>();
		MessageChannel previousOutputChannel = null;
		for (int i = 0; i < this.modules.size(); i++) {
			Module module = this.modules.get(i);
			module.initialize();
			MessageChannel inputChannel = module.getComponent("input", MessageChannel.class);
			MessageChannel outputChannel = module.getComponent("output", MessageChannel.class);
			if (i == 0 && inputChannel != null) {
				// this will act as THE input for the composite module
				// if the first module has no input, the composite is a source
				this.context.getBeanFactory().registerSingleton("input", inputChannel);
			}
			if (i > 0) {
				// first module MAY have 'input', all others MUST
				Assert.notNull(inputChannel, "each module after the first must provide 'input'");
			}
			if (previousOutputChannel != null) {
				BridgeHandler handler = new BridgeHandler();
				handler.setBeanFactory(this.context.getBeanFactory());
				handler.setOutputChannel(inputChannel);
				handler.afterPropertiesSet();
				ConsumerEndpointFactoryBean bridgeFactoryBean = new ConsumerEndpointFactoryBean();
				bridgeFactoryBean.setInputChannel(previousOutputChannel);
				bridgeFactoryBean.setHandler(handler);
				try {
					// TODO: might not be necessary to pass this context, but the FB requires non-null
					bridgeFactoryBean.setBeanFactory(this.context.getBeanFactory());
					String beanName = "bridge-" + i;
					bridgeFactoryBean.setBeanName(beanName); // avoid debug (error since 4.2.1) log from CEFB
					bridgeFactoryBean.afterPropertiesSet();
					AbstractEndpoint endpoint = bridgeFactoryBean.getObject();
					endpoints.add(endpoint);
					this.context.getBeanFactory().registerSingleton(beanName, endpoint);
					endpoint.setComponentName(beanName);
					endpoint.afterPropertiesSet();
				}
				catch (Exception e) {
					throw new IllegalStateException("failed to start bridge for CompositeModule", e);
				}
			}
			if (i < this.modules.size() - 1) {
				// last module MAY have 'output', all others MUST
				Assert.notNull(outputChannel, "each module before the last must provide 'output'");
			}
			previousOutputChannel = outputChannel;
			if (i == this.modules.size() - 1 && outputChannel != null) {
				// this will act as THE output for the composite module
				// if the final module has no outputChannel, the composite is a sink
				this.context.getBeanFactory().registerSingleton("output", outputChannel);
			}
		}
		for (int i = endpoints.size() - 1; i >= 0; i--) {
			endpoints.get(i).start();
		}
		initContext();
		if (logger.isInfoEnabled()) {
			logger.info("initialized module: " + this.toString());
		}
	}
@author Mark Fisher
@author David Turanski
@author Gary Russell
spring-xd-module/src/main/java/org/springframework/xd/module/core/CompositeModule.java