byName 根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致的bean,并将其与属性自
动装配。例如,在bean定义中将 autowire设置为by name,而该bean包含master属性(同时提供
setMaster(..)方法),Spring就会查找名为master的bean定义,并用它来装配给master属性。
比如配置文件里面有如下配置
<bean id="userInfoService" class="com.mobile.base.core.thrift.client.ThriftClientFactoryBean" autowire="byName"> <property name="className" value="com.thrift.live.UserInfoService"/> </bean>
ThriftClientFactoryBean 类如下:
package com.mobile.base.core.thrift.client; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; public class ThriftClientFactoryBean implements FactoryBean, InitializingBean { private Class ifaceClass; private Class clientClass; private String className; private ThriftClient thriftClient; public void setClassName(String className) { this.className = className; } public void setThriftClient(ThriftClient thriftClient) { this.thriftClient = thriftClient; } @Override public Object getObject() throws Exception { return Proxy.newProxyInstance(clientClass.getClassLoader(), clientClass.getInterfaces(), new ThriftProxy(thriftClient, className)); } @Override public Class<?> getObjectType() { return ifaceClass; } @Override public boolean isSingleton() { return true; } @Override public void afterPropertiesSet() throws Exception { ifaceClass = Class.forName(className + "$Iface"); clientClass = Class.forName(className + "$Client"); } class ThriftProxy implements InvocationHandler { private ThriftClient thriftClient; private String className; public ThriftProxy(ThriftClient thriftClient, String className) { this.thriftClient = thriftClient; this.className = className; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //modified by jesseling at 2015-3-12 to add detail of exception try { return method.invoke(thriftClient.get(className), args); } catch (InvocationTargetException e) { throw e.getCause(); } catch (Exception e){ throw e.getCause(); } } } }
有个属性叫thriftClient,并且有setThriftClient方法。
Spring 容器在实例化com.mobile.base.core.thrift.client.ThriftClientFactoryBean的时候,bean名字叫userInfoService,因为有autowire="byName",所以spring 会在容器里面找一个叫thriftClient的 bean,并把它注入到ThriftClientFactoryBean的属性里面(类似@Autowired),前提是ThriftClientFactoryBean有setThriftClient方法,并且spring容器里面有个bean叫ThriftClient,如下:
<bean id="thriftClient" class="com.mobile.base.core.thrift.client.ThriftClient" > </bean>
如果把autowire="byName" 去掉,或者没有setThriftClient方法,spring在实例化ThriftClientFactoryBean的时候,都不会注入thriftClient这个属性。