1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 * 19 */ 20 package org.apache.mina.integration.spring; 21 22 import java.net.SocketAddress; 23 24 import org.apache.mina.common.IoAcceptor; 25 import org.apache.mina.common.IoHandler; 26 import org.apache.mina.common.IoServiceConfig; 27 import org.springframework.beans.factory.DisposableBean; 28 import org.springframework.beans.factory.FactoryBean; 29 import org.springframework.beans.factory.InitializingBean; 30 import org.springframework.util.Assert; 31 32 /** 33 * Spring {@link FactoryBean} which enables the bindings of an {@link IoAcceptor} 34 * to be configured using Spring. Example of usage: 35 * <p> 36 * 37 * <pre> 38 * <!-- This makes it possible to specify java.net.SocketAddress values 39 * (e.g. :80 below) as Strings. 40 * They will be converted into java.net.InetSocketAddress objects by Spring. --> 41 * <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"> 42 * <property name="customEditors"> 43 * <map> 44 * <entry key="java.net.SocketAddress"> 45 * <bean class="org.apache.mina.integration.spring.InetSocketAddressEditor"/> 46 * </entry> 47 * </map> 48 * </property> 49 * </bean> 50 * 51 * <!-- The IoHandler implementation --> 52 * <bean id="httpHandler" class="com.example.MyHttpHandler"> 53 * ... 54 * </bean> 55 * 56 * <bean id="filterChainBuilder" 57 * class="org.apache.mina.integration.spring.DefaultIoFilterChainBuilderFactoryBean"> 58 * <property name="filters"> 59 * <list> 60 * <bean class="org.apache.mina.filter.LoggingFilter"/> 61 * </list> 62 * </property> 63 * </bean> 64 * 65 * <!-- By default MINA uses an ExecutorThreadModel. This demonstrates how to 66 * use your own with some non default settings. The threadModel will 67 * be set on the SocketAcceptorConfig defined below. To configure a 68 * ExecutorFilter directly you will have to use the ThreadModel.MANUAL 69 * ThreadModel instead. --> 70 * <bean id="threadModel" class="org.apache.mina.integration.spring.ExecutorThreadModelFactoryBean"> 71 * <property name="serviceName" value="HttpService"/> 72 * <property name="executor"> 73 * <bean class="org.apache.mina.integration.spring.ThreadPoolExecutorFactoryBean"> 74 * <property name="corePoolSize" value="2"/> 75 * <property name="maxPoolSize" value="10"/> 76 * <property name="keepAliveSeconds" value="30"/> 77 * </bean> 78 * </property> 79 * </bean> 80 * 81 * <bean id="ioAcceptor" class="org.apache.mina.integration.spring.IoAcceptorFactoryBean"> 82 * <property name="target"> 83 * <bean class="org.apache.mina.transport.socket.nio.SocketAcceptor"/> 84 * </property> 85 * <property name="bindings"> 86 * <list> 87 * <bean class="org.apache.mina.integration.spring.Binding"> 88 * <property name="address" value=":80"/> 89 * <property name="handler" ref="httpHandler"/> 90 * <property name="serviceConfig"> 91 * <bean class="org.apache.mina.transport.socket.nio.SocketAcceptorConfig"> 92 * <property name="filterChainBuilder" ref="filterChainBuilder"/> 93 * <property name="reuseAddress" value="true"/> 94 * <property name="threadModel" ref="threadModel"/> 95 * </bean> 96 * </property> 97 * </bean> 98 * </list> 99 * </property> 100 * </bean> 101 * </pre> 102 * 103 * </p> 104 * 105 * @author The Apache Directory Project (mina-dev@directory.apache.org) 106 * @version $Rev: 555855 $, $Date: 2007-07-13 05:19:00 +0200 (Fri, 13 Jul 2007) $ 107 */ 108 public class IoAcceptorFactoryBean implements FactoryBean, InitializingBean, 109 DisposableBean { 110 private Binding[] bindings = new Binding[0]; 111 112 private IoAcceptor target; 113 114 /** 115 * Sets the {@link IoAcceptor} to be configured using this factory bean. 116 * 117 * @param target the target {@link IoAcceptor}. 118 */ 119 public void setTarget(IoAcceptor target) { 120 this.target = target; 121 } 122 123 /** 124 * Sets the bindings to be used by the {@link IoAcceptor} configured by this 125 * factory bean. 126 * 127 * @param bindings the bindings. 128 * @throws IllegalArgumentException if the specified value is 129 * <code>null</code>. 130 * @see IoAcceptor#bind(SocketAddress, IoHandler) 131 * @see IoAcceptor#bind(SocketAddress, IoHandler, IoServiceConfig) 132 * @see Binding 133 */ 134 public void setBindings(Binding[] bindings) { 135 Assert.notNull(bindings, "Property 'bindings' may not be null"); 136 this.bindings = bindings; 137 } 138 139 public Object getObject() throws Exception { 140 return target; 141 } 142 143 public Class getObjectType() { 144 return IoAcceptor.class; 145 } 146 147 public boolean isSingleton() { 148 return true; 149 } 150 151 public void afterPropertiesSet() throws Exception { 152 Assert.notNull(target, "Property 'target' may not be null"); 153 154 /* 155 * Bind all. 156 */ 157 for (int i = 0; i < bindings.length; i++) { 158 Binding b = bindings[i]; 159 if (b.getServiceConfig() != null) { 160 target.bind(b.getAddress(), b.getHandler(), b 161 .getServiceConfig()); 162 } else { 163 target.bind(b.getAddress(), b.getHandler()); 164 } 165 } 166 } 167 168 public void destroy() throws Exception { 169 for (int i = 0; i < bindings.length; i++) { 170 Binding b = bindings[i]; 171 try { 172 target.unbind(b.getAddress()); 173 } catch (Exception ignored) { 174 } 175 } 176 } 177 }