getBean方法得到context中的bean,傳入的參數是name。 java
有理由相信,context中有一個map,map的key就是name,value則是一個beanFactory。 redis
疑問:接口或者抽象類能夠導入context嗎? spring
答案:不能。setNameAware這些須要對context配置中的類調用setName方法。雖然abstract能夠產生class文件,但他被反射建立倒是不能夠的。 spa
spring找那些能夠裝入容器的class文件,會把這些class實現的接口以及繼承自的父類信息都會添加到context中。因此在spring.xml文件中看到抽象類定義時,須要加上abstract="true"標誌。 代理
<bean id="redisDao" class="com.ec.dao.impl.RedisDao" abstract="true"> <property name="config" ref="config" /> <property name="redisConnectionPool" ref="redisConnectionPool" /> <property name="redisConnectionPool1" ref="redisConnectionPool1" /> </bean>
說spring保存了class的接口信息和parent class信息是有根據的。在咱們使用bean時,經過@Resource標籤,咱們只是定義一個接口,spring就能夠把實現該接口的對象注入。當有多個實現時,就得用到@Autowired,經過定義bean name來注入。 code
充分利用了反射機制: xml
想象一下吧,若是沒有反射機制,xml中的這些bean該如何被產生?咱們本身new?那spring也就沒有太多存在的價值了。 對象
在反射機制之上,利用代理實現AOP,也就顯得那麼順其天然了。 繼承
private final static Class[] constructorParams = { InvocationHandler.class }; public static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) throws IllegalArgumentException { if (h == null) { throw new NullPointerException(); } /* * Look up or generate the designated proxy class. */ Class cl = getProxyClass(loader, interfaces); /* * Invoke its constructor with the designated invocation handler. */ try { Constructor cons = cl.getConstructor(constructorParams); return (Object) cons.newInstance(new Object[] { h }); } catch (NoSuchMethodException e) { throw new InternalError(e.toString()); } catch (IllegalAccessException e) { throw new InternalError(e.toString()); } catch (InstantiationException e) { throw new InternalError(e.toString()); } catch (InvocationTargetException e) { throw new InternalError(e.toString()); } }再看看
InvocationHandler.class是個什麼玩意
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;返回的Object裏面能夠動態實現一些接口,spring就能夠在模板中利用這些接口來作文章了。