複合コンポーネント内のh:commandButtonに複数のactionListenerを指定する方法

#目的
複合コンポーネントの引数として受け取ったactionListenerを使用し、h:commandButton、h:commandLinkに複数指定したい際の実装方法です。

#問題点
引数のlistener2、3をf:actionListenerで実行しようとしたところエラーとなってしまいました。
※h:commandListenerの属性として指定したlistener1とactionはエラーにならなかった

```TestListener.java
public void method1() {
	System.out.println("method1");
}
public void method2() {
	System.out.println("method2");
}
public void method3() {
	System.out.println("method3");
}
public void method4() {
	System.out.println("method4");
}
```

```multiListener.xhtml
<cc:interface>
	<cc:attribute name="listener1" method-signature="void actionListener(javax.faces.event.ActionEvent)"></cc:attribute>
	<cc:attribute name="listener2" method-signature="void actionListener(javax.faces.event.ActionEvent)"></cc:attribute>
	<cc:attribute name="listener3" method-signature="void actionListener(javax.faces.event.ActionEvent)"></cc:attribute>
	<cc:attribute name="action" method-signature="java.lang.Object action()"></cc:attribute>
</cc:interface>
<cc:implementation>
	<h:commandButton value="cc1"
				actionListener="#{cc.attrs.listener1}"
					action="#{cc.attrs.action}">
		<f:actionListener binding="#{cc.attrs.listener2}"/>
		<f:actionListener binding="#{cc.attrs.listener3}"/>
	</h:commandButton>
</cc:implementation>
```
```Test.xhtml
<my:multiListener listener1="#{testListener.method1()}"
					listener2="#{testListener.method2()}"
					listener3="#{testListener.method3()}"
					action="#{testListener.method4()}"/>
```
```
javax.servlet.ServletException: Cannot convert com.sun.faces.facelets.el.ContextualCompositeMethodExpression@70723673 of type class com.sun.faces.facelets.el.ContextualCompositeMethodExpression to interface javax.faces.event.ActionListener
	at javax.faces.api@3.0.0.Final//javax.faces.webapp.FacesServlet.executeLifecyle(FacesServlet.java:725)
	at javax.faces.api@3.0.0.Final//javax.faces.webapp.FacesServlet.service(FacesServlet.java:451)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
	at io.opentracing.contrib.opentracing-jaxrs2//io.opentracing.contrib.jaxrs2.server.SpanFinishingFilter.doFilter(SpanFinishingFilter.java:52)
	at io.undertow.servlet@2.0.26.Final//io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
・・・

```

#実装方法

複合コンポーネントの引数で指定したメソッドは「ContextualCompositeMethodExpression」でラップされる（という表現が正しいかはわからないが）ようで、f:actionListenerを使用する場合はそこを考慮した実装にする必要があるようです。

##実装方法①
```multiListener.xhtml
<h:commandButton value="cc1"
				actionListener="#{cc.attrs.listener1}"
				action="#{cc.attrs.action}">
	<f:actionListener binding="#{cc.attrs.listener2.invoke(facesContext.getCurrentInstance().getELContext(), null)}"/>
	<f:actionListener binding="#{cc.attrs.listener3.invoke(facesContext.getCurrentInstance().getELContext(), null)}"/>
</h:commandButton>
```

##実装方法②
```multiListener.xhtml
<h:commandButton value="cc2"
				action="#{testListener.execute(cc.attrs.listener1,cc.attrs.listener2,cc.attrs.listener3,cc.attrs.action)}">
</h:commandButton>
```

```TestListener.java
	public Object execute(ContextualCompositeMethodExpression listener1
			, ContextualCompositeMethodExpression listener2
			, ContextualCompositeMethodExpression listener3
			, ContextualCompositeMethodExpression action) {
		ELContext el = FacesContext.getCurrentInstance().getELContext();
		listener1.invoke(el, null);
		listener2.invoke(el, null);
		listener3.invoke(el, null);
		return action.invoke(el, null);
	}
```

##結果
①、②ともに以下のようになりました。

```
14:43:31,276 INFO  [stdout] (default task-1) method1

14:43:31,276 INFO  [stdout] (default task-1) method2

14:43:31,276 INFO  [stdout] (default task-1) method3

14:43:31,277 INFO  [stdout] (default task-1) method4
```