a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 96|回复: 0

[专业语言] JAVA认证:Spring的学习原理是注入

[复制链接]
发表于 2012-8-4 12:44:44 | 显示全部楼层 |阅读模式
首先我们来看看 Spring 参考文档的 11.2.6. 执行SQL语句 这里有个代码片段:
/ D6 w  S. T/ O& @  import javax.sql.DataSource;import org.springframework.jdbc.core.JdbcTemplate;public class ExecuteAStatement public void setDataSource }1 X1 i0 O7 x9 k# X9 ]
  这个就是通俗的 Java 类, 再参考 11.2.4. DataSource接口, 这里的另一个代码片段:
; f3 G) y  U: J1 T3 H; _  DriverManagerDataSource dataSource = new DriverManagerDataSource;dataSource.setDriverClassName;dataSource.setUrl;dataSource.setUsername;dataSource.setPassword;. U$ J1 }& V" I' |. g
  当然膳缦沔的毗连体例可以设置装备摆设成我们课程琅缦沔介绍的 MyEclipse Derby 的数据库毗连:
* @/ ^1 p: j' T' ^  org.apache.derby.jdbc.ClientDriverjdbc:derby://localhost:1527/myeclipse;create=trueappapp. O5 e$ N0 W# b$ X6 ~$ c& o
  我们可以写一个测试类来执行代码:4 g2 y1 y3 }  p8 T# b4 V2 b0 C
  import org.springframework.jdbc.datasource.DriverManagerDataSource;public class TestTemplate }( X; B5 {1 y1 e1 c  G& w% k- y
  这个代码可以跑通, 就是通俗的编程体例, 巨匠可以去看适才介绍的文档四周的具体声名。
/ U9 b4 H* K9 v' Y  那么假如用 Spring 来做, 代码会酿成这样:" ?9 N% ~- i$ D2 j5 V! x/ y
  ExecuteAStatement 类代码连结不变, 多了个 beans.xml:
/ }; S9 ?$ o. N  ExecuteAStatement 类代码连结不变, 多了个 beans.xml:/ ~9 g% m$ a, F. c
  ?xml version="1.0" encoding="UTF-8"?/ d- U; {# u4 [
  beans
  C9 j; h) B; S$ M  xmlns="http://www.springframework.org/schema/beans"! c* `7 w+ T( O- ?0 C" O4 i$ g+ ]- c
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/ K9 g# ]( I% }- i8 ^: w4 @. J7 `
  xsi:schemaLocation="http://www.springframework.org/schema/beans                      http://www.springframework.org/schema/beans/spring-beans-2.0.xsd", {0 p2 M% [1 |, [
  bean id="userDAO"
+ ~) x+ ~5 ?- @" w; I# ~# B/ _  property name="dataSource"- R6 `/ _( z3 d) \
  ref bean="myDataSource" /
* Q, J( C* ~- j; B) [3 m: M  /property# b' ^9 w) Y. p# {: [
  /bean7 h' \; P$ u! Y2 g7 ]& y
  bean id="myDataSource"
1 h2 o( R7 j3 u& u; T* V  property name="driverClassName"
" S" ~" S4 y4 W1 T7 h" Q2 }) D  valueorg.hsqldb.jdbcDriver/value
1 A" w3 Q5 w4 g1 T2 x! a% _/ J  /property0 d5 N( D! c! H  |9 c9 d
  property name="url"
8 e7 Q6 B0 E2 P) l3 P  valuejdbc:hsqldb:hsql://localhost:/value
1 Q2 \0 L2 S' J( Y; [* v) Z: m  /property
9 V' M+ P* D, x  property name="username"
  o& O+ e; J% n  valuesa/value
) q4 }( y; c* P* Z  /property1 o' F+ Q) i/ \% I( [2 w5 w# Q: @% c
  property name="password"3 ?+ q0 _5 y$ b0 Y- L! z
  value/value
. p* @( k) v- W" N( B3 e  /property
$ h6 h0 l+ Y1 R3 p! m" U  /bean  i- H1 U6 P) j# N% X) ~4 \3 ~
  /beans
! b/ m8 n# S3 `% O5 t8 ^# J0 c  测试类:
, t$ v, m- _" e  import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test }  y" ]2 R. m# X2 N& b2 m
  和膳缦沔的 TestTemplate 类对比, 就会发现 new DriverManagerDataSource() 这个过程不用我们写了, 运行的时辰会发现一切都执行的好好的, 也就是常说的 ExecuteAStatement 的 dataSource 这个属性被注入了。2 m5 }9 @& [! ?' i
  那么这个过程到底该若何理解呢? Spring 是一个对象池, 可以简化为一个 Map, 存多个主键和对象的映射。 那么 Spring 运行的过程中, 会按照 beans.xml 一步步进行需要的解析工作:% {* Q  b& Z0 @6 n
  Map springEngine = new HashMap();
+ c9 y: _' C( M3 L( B  OK, 解析到了
8 E3 {. _" s0 Q0 ?  bean id="userDAO" , 发现 bean 界说, 那就新建一个实例存到对象池里吧, 主键就是 userDAO, 值就是对象:
8 X5 |: X3 ^8 d1 ]  k; o  ExecuteAStatement bean1 = new ExecuteAStatement();
  h) |7 y# k$ H/ q  springEngine.put("userDAO", bean1);  V$ r( T  y1 g( k/ |  Z
  再往下执行, 发现 property 界说:5 v, J* k- E9 R  h
  property name="dataSource"
/ }$ u& S/ e! k& v  到了这里, 就知道应该挪用 bean1.setDataSource(DataSource) 体例了。 可以接着执行, 发现: B% f* H6 z7 E8 h6 q
  ref bean="myDataSource" /, 哦, 这个体例的参数还没有呢, 是个 bean 的引用, 好了, 要挪用这个体例, 仍是先 new 一个名字为 myDataSource 的 bean2 吧。 就跳到下面寻找 myDataSource 的界说, 找到了:5 |* {# l/ |" ^; B4 a
  bean id="myDataSource"property name="driverClassName"valueorg.hsqldb.jdbcDriver/value/propertyproperty name="url"valuejdbc:hsqldb:hsql://localhost:/value/propertyproperty name="username"valuesa/value/propertyproperty name="password"value/value/property /bean1 f# i* L1 {' [  b" t, q& ?, ^1 K
  像以前一样, 先实例化这个类, 然后看到 property 神色就挪用对应的 setXxx() 这样的体例, 相当于下面一段代码:
/ p5 O) b) o% x) l" C8 U" t  // 新建一个数据源对象DriverManagerDataSource bean2 = new DriverManagerDataSource;bean2.setDriverClassName;bean2.setUrl;bean2.setUsername;bean2.setPassword;
$ E* C7 ^/ x: E# o: ^3 ?  不是还有个 bean 的 id 名字为 myDataSource 嘛, 那就把它存到对象池琅缦沔:
) }9 Z* O$ Q/ D2 b  springEngine.put("myDataSource", bean2);
2 h, G% s1 p/ @9 S8 c' x  好了, 最后就是把他们两个联系关系起来了, 经由过程 ref 里指定的 bean id 名来联系关系起来:
: n! t5 W7 D! G& `: V  // 省略类型转换的代码9 a' u1 `* G4 ?' [2 K0 z
  springEngine.get("userDAO")。setDataSource(springEngine.get("myDataSource"));
6 ~/ G/ Q. ]4 o% Z& O; y  最后返回给用户的就是一个对象池(一个 Map)了, 所以别人挪用的时辰, 就发现 springEngine.get("userDAO") 回来的类的 dataSource 属性已经被实例化过了, 这些都是 Spring 幕后工作的代码, 经由过程反射机制来实现。
7 d4 E: }9 j/ K. r  b' S, S( |  所以最后写代码挪用:( a6 s! U: J/ l9 S4 C8 [. s
  context.getBean("userDAO") 的时辰, 获得的是 ExecuteAStatement, 这时辰还有一个 myDataSource, 也可以被挪用:
5 H  |7 c4 b# T  context.getBean("myDataSource"), 获得的是 DriverManagerDataSource.
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-5-7 06:52 , Processed in 0.214892 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表