<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Java豆技术站点 &#187; ioc</title>
	<atom:link href="http://javadou.com/tag/ioc/feed/" rel="self" type="application/rss+xml" />
	<link>http://javadou.com</link>
	<description>Java</description>
	<lastBuildDate>Thu, 12 Aug 2010 09:01:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Spring教程ioc 依赖注入原理学习</title>
		<link>http://javadou.com/spring-ioc-yuanli-234/</link>
		<comments>http://javadou.com/spring-ioc-yuanli-234/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 19:29:00 +0000</pubDate>
		<dc:creator>阿超</dc:creator>
				<category><![CDATA[Spring]]></category>
		<category><![CDATA[recommend]]></category>
		<category><![CDATA[ioc]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://javadou.com/spring-ioc-yuanli-234/</guid>
		<description><![CDATA[和上面的 TestTemplate 类相比, 就会发现 new DriverManagerDataSource() 这个过程不用我们写了, 运行的时候会发现一切都执行的好好的, 也就是常说的 ExecuteAStatement 的 dataSource 这个属性被注入了. 

那么这个过程到底该如何理解... ]]></description>
			<content:encoded><![CDATA[<p>首先我们来看看 Spring 参考文档的 11.2.6. 执行SQL语句 这里有个代码片断:</p>
<p>import javax.sql.DataSource;   <br />import org.springframework.jdbc.core.JdbcTemplate;</p>
<p>public class ExecuteAStatement {</p>
<p>&#160;&#160;&#160; private JdbcTemplate jt;   <br />&#160;&#160;&#160; private DataSource dataSource;</p>
<p>&#160;&#160;&#160; public void doExecute() {   <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; jt = new JdbcTemplate(dataSource);    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; jt.execute(&quot;create table mytable (id integer, name varchar(100))&quot;);     <br />&#160;&#160;&#160; }</p>
<p>&#160;&#160;&#160; public void setDataSource(DataSource dataSource) {   <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.dataSource = dataSource;    <br />&#160;&#160;&#160; }    <br />}</p>
<p>这个就是普通的 Java 类, 再参考 11.2.4. DataSource接口, 这里的另一个代码片断:   <br />DriverManagerDataSource dataSource = new DriverManagerDataSource();    <br />dataSource.setDriverClassName(&quot;org.hsqldb.jdbcDriver&quot;);    <br />dataSource.setUrl(&quot;jdbc:hsqldb:hsql://localhost:&quot;);    <br />dataSource.setUsername(&quot;sa&quot;);    <br />dataSource.setPassword(&quot;&quot;);</p>
<p>当然上面的连接方式可以配置成我们课程里面介绍的 MyEclipse Derby 的数据库连接:   <br />org.apache.derby.jdbc.ClientDriver    <br />jdbc:derby://localhost:1527/myeclipse;create=true    <br />app    <br />app</p>
<p>我们可以写一个测试类来执行代码:</p>
<p>import org.springframework.jdbc.datasource.DriverManagerDataSource;</p>
<p>public class TestTemplate {   <br />&#160; public static void main(String[] args) {    <br />&#160;&#160;&#160; // 新建一个数据源对象    <br />&#160;&#160;&#160; DriverManagerDataSource dataSource = new DriverManagerDataSource();    <br />&#160;&#160;&#160; dataSource.setDriverClassName(&quot;org.hsqldb.jdbcDriver&quot;);    <br />&#160;&#160;&#160; dataSource.setUrl(&quot;jdbc:hsqldb:hsql://localhost:&quot;);    <br />&#160;&#160;&#160; dataSource.setUsername(&quot;sa&quot;);    <br />&#160;&#160;&#160; dataSource.setPassword(&quot;&quot;);    <br />&#160;&#160;&#160; // 新建一个ExecuteAStatement 对象    <br />&#160;&#160;&#160; ExecuteAStatement eas = new ExecuteAStatement();    <br />&#160;&#160;&#160; // 给执行表达式的对象关联数据源(也就是常说的注入, 通过 JavaBean 的 setXxx 方法关联起来)    <br />&#160;&#160;&#160; eas.setDataSource(dataSource);    <br />&#160;&#160;&#160; // 执行功能代码    <br />&#160;&#160;&#160; eas.doExecute();    <br />&#160; }    <br />}</p>
<p>这个代码可以跑通, 就是普通的编程方式, 大家可以去看刚才介绍的文档附近的详细说明.</p>
<p>那么如果用 Spring 来做, 代码会变成这样:   <br />ExecuteAStatement 类代码保持不变, 多了个 beans.xml:    <br />&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;    <br />&lt;beans    <br /> xmlns=&quot;http://www.springframework.org/schema/beans&quot;    <br /> xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;    <br /> xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd&quot;&gt;</p>
<p> &lt;bean id=&quot;userDAO&quot; class=&quot;ExecuteAStatement&quot;&gt;   <br />&#160; &lt;property name=&quot;dataSource&quot;&gt;    <br />&#160;&#160; &lt;ref bean=&quot;myDataSource&quot; /&gt;    <br />&#160; &lt;/property&gt;    <br /> &lt;/bean&gt;</p>
<p> &lt;bean id=&quot;myDataSource&quot;   <br />&#160; class=&quot;org.springframework.jdbc.datasource.DriverManagerDataSource&quot;&gt;    <br />&#160; &lt;property name=&quot;driverClassName&quot;&gt;    <br />&#160;&#160;&#160;&#160;&#160; &lt;value&gt;org.hsqldb.jdbcDriver&lt;/value&gt;    <br />&#160; &lt;/property&gt;    <br />&#160; &lt;property name=&quot;url&quot;&gt;    <br />&#160;&#160;&#160;&#160;&#160; &lt;value&gt;jdbc:hsqldb:hsql://localhost:&lt;/value&gt;    <br />&#160; &lt;/property&gt;    <br />&#160; &lt;property name=&quot;username&quot;&gt;    <br />&#160;&#160;&#160;&#160;&#160; &lt;value&gt;sa&lt;/value&gt;    <br />&#160; &lt;/property&gt;    <br />&#160; &lt;property name=&quot;password&quot;&gt;    <br />&#160;&#160;&#160;&#160;&#160; &lt;value&gt;&lt;/value&gt;    <br />&#160; &lt;/property&gt;&#160;&#160;&#160;&#160;&#160;&#160; <br /> &lt;/bean&gt;</p>
<p>&lt;/beans&gt;</p>
<p>测试类:</p>
<p>import org.springframework.context.ApplicationContext;   <br />import org.springframework.context.support.ClassPathXmlApplicationContext;</p>
<p>public class Test {</p>
<p> public static void main(String[] args) throws IOException {   <br />&#160; ApplicationContext context = new ClassPathXmlApplicationContext(&quot;beans.xml&quot;);    <br />&#160; ExecuteAStatement eas =(ExecuteAStatement)context.getBean(&quot;userDAO&quot;);    <br />&#160;&#160;&#160;&#160;&#160; // 执行功能代码    <br />&#160;&#160;&#160;&#160;&#160; eas.doExecute();    <br /> }    <br />}</p>
<p>和上面的 TestTemplate 类相比, 就会发现 new DriverManagerDataSource() 这个过程不用我们写了, 运行的时候会发现一切都执行的好好的, 也就是常说的 ExecuteAStatement 的 dataSource 这个属性被注入了. </p>
<p>那么这个过程到底该如何理解呢? Spring 是一个对象池, 可以简化为一个 Map, 存多个主键和对象的映射. 那么 Spring 运行的过程中, 会根据 beans.xml 一步步进行必要的解析工作:</p>
<p>Map springEngine = new HashMap();</p>
<p>OK, 解析到了   <br />&lt;bean id=&quot;userDAO&quot; class=&quot;ExecuteAStatement&quot;&gt;, 发现 bean 定义, 那就新建一个实例存到对象池里吧, 主键就是 userDAO, 值就是对象:    <br />ExecuteAStatement bean1 = new ExecuteAStatement();    <br />springEngine.put(&quot;userDAO&quot;, bean1);</p>
<p>再往下执行, 发现 property 定义:   <br />&lt;property name=&quot;dataSource&quot;&gt;    <br />到了这里, 就知道应该调用 bean1.setDataSource(DataSource) 方法了. 可以接着执行, 发现    <br />&lt;ref bean=&quot;myDataSource&quot; /&gt;, 哦, 这个方法的参数还没有呢, 是个 bean 的引用, 好了, 要调用这个方法, 还是先 new 一个名字为 myDataSource 的 bean2 吧. 就跳到下面寻找 myDataSource 的定义, 找到了:    <br /> &lt;bean id=&quot;myDataSource&quot;    <br />&#160; class=&quot;org.springframework.jdbc.datasource.DriverManagerDataSource&quot;&gt;    <br />&#160; &lt;property name=&quot;driverClassName&quot;&gt;    <br />&#160;&#160;&#160;&#160;&#160; &lt;value&gt;org.hsqldb.jdbcDriver&lt;/value&gt;    <br />&#160; &lt;/property&gt;    <br />&#160; &lt;property name=&quot;url&quot;&gt;    <br />&#160;&#160;&#160;&#160;&#160; &lt;value&gt;jdbc:hsqldb:hsql://localhost:&lt;/value&gt;    <br />&#160; &lt;/property&gt;    <br />&#160; &lt;property name=&quot;username&quot;&gt;    <br />&#160;&#160;&#160;&#160;&#160; &lt;value&gt;sa&lt;/value&gt;    <br />&#160; &lt;/property&gt;    <br />&#160; &lt;property name=&quot;password&quot;&gt;    <br />&#160;&#160;&#160;&#160;&#160; &lt;value&gt;&lt;/value&gt;    <br />&#160; &lt;/property&gt;&#160;&#160;&#160;&#160;&#160;&#160; <br /> &lt;/bean&gt;    <br />像以前一样, 先实例化这个类, 然后看到 property 表情就调用对应的 setXxx() 这样的方法, 相当于下面一段代码:    <br />&#160;&#160;&#160; // 新建一个数据源对象    <br />&#160;&#160;&#160; DriverManagerDataSource bean2 = new DriverManagerDataSource();    <br />&#160;&#160;&#160; bean2.setDriverClassName(&quot;org.hsqldb.jdbcDriver&quot;);    <br />&#160;&#160;&#160; bean2.setUrl(&quot;jdbc:hsqldb:hsql://localhost:&quot;);    <br />&#160;&#160;&#160; bean2.setUsername(&quot;sa&quot;);    <br />&#160;&#160;&#160; bean2.setPassword(&quot;&quot;);    <br />不是还有个 bean 的 id 名字为 myDataSource 嘛, 那就把它存到对象池里面:</p>
<p>springEngine.put(&quot;myDataSource&quot;, bean2);</p>
<p>好了, 最后就是把他们两个关联起来了, 通过 ref 里指定的 bean id 名来关联起来:</p>
<p>// 省略类型转换的代码   <br />springEngine.get(&quot;userDAO&quot;).setDataSource(springEngine.get(&quot;myDataSource&quot;));</p>
<p>最后返回给用户的就是一个对象池(一个 Map)了, 所以别人调用的时候, 就发现 springEngine.get(&quot;userDAO&quot;) 回来的类的 dataSource 属性已经被实例化过了, 这些都是 Spring 幕后工作的代码, 通过反射机制来实现.</p>
<p>所以最后写代码调用:   <br />context.getBean(&quot;userDAO&quot;) 的时候, 得到的是 ExecuteAStatement, 这时候还有一个 myDataSource, 也可以被调用:    <br />context.getBean(&quot;myDataSource&quot;), 得到的是 DriverManagerDataSource.</p>
<p>介绍的过程, 仅供参考. 欢迎大家交流更好的原理介绍文章.</p>
<p>再转一篇别人推荐的通俗易懂的说明, 非实现方面的:</p>
<p>IoC就是Inversion of Control，控制反转。在Java开发中，IoC意味着将你设计好的类交给系统去控制，而不是在你的类内部控制。这称为控制反转。    <br />下面我们以几个例子来说明什么是IoC     <br />假设我们要设计一个Girl和一个Boy类，其中Girl有kiss方法，即Girl想要Kiss一个Boy。那么，我们的问题是，Girl如何能够认识这个Boy？     <br />在我们中国，常见的MM与GG的认识方式有以下几种     <br />1 青梅竹马； 2 亲友介绍； 3 父母包办     <br />那么哪一种才是最好呢？     <br />青梅竹马：Girl从小就知道自己的Boy。     <br />public class Girl {     <br />void kiss(){     <br />Boy boy = new Boy();     <br />}     <br />}     <br />然而从开始就创建的Boy缺点就是无法在更换。并且要负责Boy的整个生命周期。如果我们的Girl想要换一个怎么办？（严重不支持Girl经常更换Boy,#_#）     <br />亲友介绍：由中间人负责提供Boy来见面     <br />public class Girl {     <br />void kiss(){     <br />Boy boy = BoyFactory.createBoy();     <br />}     <br />}     <br />亲友介绍，固然是好。如果不满意，尽管另外换一个好了。但是，亲友BoyFactory经常是以Singleton的形式出现，不然就是，存在于 Globals，无处不在，无处不能。实在是太繁琐了一点，不够灵活。我为什么一定要这个亲友掺和进来呢？为什么一定要付给她介绍费呢？万一最好的朋友爱上了我的男朋友呢？     <br />父母包办：一切交给父母，自己不用费吹灰之力，只需要等着Kiss就好了。     <br />public class Girl {     <br />void kiss(Boy boy){     <br />// kiss boy     <br />boy.kiss();     <br />}     <br />}     <br />Well，这是对Girl最好的方法，只要想办法贿赂了Girl的父母，并把Boy交给他。那么我们就可以轻松的和Girl来Kiss了。看来几千年传统的父母之命还真是有用哦。至少Boy和Girl不用自己瞎忙乎了。     <br />这就是IOC，将对象的创建和获取提取到外部。由外部容器提供需要的组件。     <br />我们知道好莱坞原则：“Do not call us, we will call you.” 意思就是，You, girlie, do not call the boy. We will feed you a boy。     <br />我们还应该知道依赖倒转原则即 Dependence Inversion Princinple，DIP     <br />Eric Gamma说，要面向抽象编程。面向接口编程是面向对象的核心。     <br />组件应该分为两部分，即 Service, 所提供功能的声明 Implementation, Service的实现     <br />好处是：多实现可以任意切换，防止 “everything depends on everything” 问题．即具体依赖于具体。     <br />所以，我们的Boy应该是实现Kissable接口。这样一旦Girl不想kiss可恶的Boy的话，还可以kiss可爱的kitten和慈祥的grandmother。     <br />二、IOC的type     <br />IoC的Type指的是Girl得到Boy的几种不同方式。我们逐一来说明。     <br />IOC type 0：不用IOC     <br />public class Girl implements Servicable {     <br />private Kissable kissable;     <br />public Girl() {     <br />kissable = new Boy();     <br />}     <br />public void kissYourKissable() {     <br />kissable.kiss();     <br />}     <br />}     <br />Girl自己建立自己的Boy，很难更换，很难共享给别人，只能单独使用，并负责完全的生命周期。     <br />IOC type 1，先看代码：代码     <br />public class Girl implements Servicable {     <br />Kissable kissable;     <br />public void service(ServiceManager mgr) {     <br />kissable = (Kissable) mgr.lookup(“kissable”);     <br />}     <br />public void kissYourKissable() {     <br />kissable.kiss();     <br />}     <br />}     <br />这种情况出现于Avalon Framework。一个组件实现了Servicable接口，就必须实现service方法，并传入一个ServiceManager。其中会含有需要的其它组件。只需要在service方法中初始化需要的Boy。     <br />另外，J2EE中从Context取得对象也属于type 1。它依赖于配置文件。     <br />IOC type 2：     <br />public class Girl {     <br />private Kissable kissable;     <br />public void setKissable(Kissable kissable) {     <br />this.kissable = kissable;     <br />}     <br />public void kissYourKissable() {     <br />kissable.kiss();     <br />}     <br />}     <br />Type 2出现于Spring Framework，是通过JavaBean的set方法来将需要的Boy传递给Girl。它必须依赖于配置文件。     <br />IOC type 3:     <br />public class Girl {     <br />private Kissable kissable;     <br />public Girl(Kissable kissable) {     <br />this.kissable = kissable;     <br />}     <br />public void kissYourKissable() {     <br />kissable.kiss();     <br />}     <br />}     <br />这就是PicoContainer的组件 。通过构造函数传递Boy给Girl     <br />PicoContainer container = new DefaultPicoContainer();     <br />container.registerComponentImplementation(Boy.class);     <br />container.registerComponentImplementation(Girl.class);     <br />Girl girl = (Girl) container.getComponentInstance(Girl.class);     <br />girl.kissYourKissable();     <br />参考资料     <br />1 http://www.picocontainer.org/presentations/JavaPolis2003.ppt    <br />http://www.picocontainer.org/presentations/JavaPolis2003.pdf    <br />2 DIP， Robert C Martin, Bob大叔的优秀论文     <br />http://www.objectmentor.com/resources/articles/dip.pdf    <br />3 Dependency Injection 依赖注射，Matrin Fowler对DIP的扩展     <br />http://www.martinfowler.com/articles/injection.html    <br />4 IOC框架     <br />PicoContainer 优秀的IOC框架     <br />http://picocontainer.org/    <br />Avalon     <br />http://avalon.apache.org/    <br />Spring Framework     <br />http://www.springframework.org/    <br />HiveMind     <br />http://jakarta.apache.org/commons/hivemind    <br />&#8212;-    <br />IoC是一种模式     <br />IoC(Inversion of Control)中文译为控制反转，目前Java社群中流行的各种轻量级容器的实现都是以IoC模式作为基础的。控制反转意味着在系统开发过程中，设计的类将交由容器去控制，而不是在类的内部去控制，类与类之间的关系将交由容器处理,一个类在需要调用另一个类时,只要调用另一个类在容器中注册的名字就可以得到这个类的实例,与传统的编程方式有了很大的不同,”不用你找,我来提供给你”,这就是控制反转的含义。Martin Fowler在他的一篇文章中给IoC起了一个更为直观的名字：依赖注射DI(Dependency Injection)。下面先引入这个模式。     <br />在设计模式中，我们已经习惯一种思维编程方式：Interface Driven Design 接口驱动，接口驱动有很多好处，可以提供不同灵活的子类实现，增加代码稳定和健壮性等等，但是接口一定是需要实现的，也就是如下语句迟早要执行：     <br />InterfaceA a = new InterfaceAImp()；     <br />InterfaceAImp 是接口InterfaceA的一个子类，IoC模式可以延缓接口的实现，根据需要实现，有个比喻：接口如同空的模型套，在必要时，需要向模型套注射石膏，这样才能成为一个模型实体，因此，我们将人为控制接口的实现成为注射。IoC模式是解决调用者和被调用者之间的一种关系，上述InterfaceA实现语句表明当前是在调用被调用者InterfaceAImp，由于被调用者名称写入了调用者的代码中，这产生了一个接口实现的原罪：彼此联系，调用者和被调用者有紧密联系，在UML中是用依赖 Dependency 表示。但是这种依赖在分离关注的思维下是不可忍耐的，必须切割，实现调用者和被调用者解耦，新的Ioc模式依赖注射 (Dependency Injection)模式由此产生了，也就是将依赖先剥离，然后在适当时候再注射进入。 </p>
]]></content:encoded>
			<wfw:commentRss>http://javadou.com/spring-ioc-yuanli-234/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IOC 后台机制学习&#8211;转</title>
		<link>http://javadou.com/ioc-study-233/</link>
		<comments>http://javadou.com/ioc-study-233/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 18:26:00 +0000</pubDate>
		<dc:creator>阿超</dc:creator>
				<category><![CDATA[Spring]]></category>
		<category><![CDATA[ioc]]></category>

		<guid isPermaLink="false">http://javadou.com/ioc-study-233/</guid>
		<description><![CDATA[题目: IOC 后台机制学习 
给定: 
配置文件 config.txt, 文件内容 
className = test.JavaBean1 
field = username 
value = ABC 
该文件中的三个值会随时可能变化, 唯一不变的是 className 指定的都是一个 JavaBean(为了简化, 我们假定里面已经... ]]></description>
			<content:encoded><![CDATA[<p>转自beansoft</p>
<p>题目: IOC 后台机制学习    <br />给定:     <br />配置文件 config.txt, 文件内容     <br />className = test.JavaBean1     <br />field = username     <br />value = ABC     <br />该文件中的三个值会随时可能变化, 唯一不变的是 className 指定的都是一个 JavaBean(为了简化, 我们假定里面已经有一个 username 属性, 例如:     <br />class JavaBeanxxxx {     <br />&#160;&#160;&#160; private String username;     <br />&#160;&#160;&#160; public String getUsername() {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return username;     <br />&#160;&#160;&#160; }     <br />&#160;&#160;&#160; public void setUsername(String uname) {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.username = uname;     <br />&#160;&#160;&#160; }     <br />}     <br />要求: 写一段代码, 读取配置文件 config.txt, 然后实现把 className 指定的 JavaBean 类加载(注意这个类名是可以修改的, 可配置的), 然后生成一个实例,     <br />并把配置文件中field字段指定的值作为这个实例的属性名(这里是username)所对应的值设置为 ABC(字符串), 并且要读出最后设置的值.     <br />此题已经被 TigerTian 解答出来, 欢迎学习, 也感谢 TigerTian:</p>
<pre class="java">

package com.gcoresoft.ioc;import java.io.*;import java.lang.reflect.*;import java.util.*;import java.beans.*;public class IOCStudy {//Load the properties fileprivate Properties prop=new Properties();public void loadPropFile(String filename)&#160;&#160;&#160; {try&#160;&#160;&#160;&#160;&#160;&#160;&#160; {&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FileInputStream fin=new FileInputStream(filename);&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; prop.load(fin);&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; fin.close();&#160;&#160;&#160;&#160;&#160;&#160;&#160; }catch(Exception e){&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.out.println(e.toString());&#160;&#160;&#160;&#160;&#160;&#160;&#160; }&#160;&#160;&#160; }private String getValueByName(String Name)&#160;&#160;&#160; {return prop.getProperty(Name);&#160;&#160;&#160; }public static void main(String[] args)&#160;&#160;&#160; {&#160;&#160;&#160;&#160;&#160;&#160;&#160; IOCStudy ioc=new IOCStudy();&#160;&#160;&#160;&#160;&#160;&#160;&#160; ioc.loadPropFile(&quot;E:\\Work\\GetInIOC\\src\\com\\gcoresoft\\ioc\\Config.txt&quot;);try&#160;&#160;&#160;&#160;&#160;&#160;&#160; {&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Class bean=Class.forName(ioc.getValueByName(&quot;className&quot;));try {&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; java.beans.BeanInfo info=java.beans.Introspector.getBeanInfo(bean);&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; java.beans.PropertyDescriptor pd[]=info.getPropertyDescriptors();try {&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method mSet=null,mRead=null;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Object obj=bean.newInstance();for(int i=0;i&lt;pd.length;i++)if(pd[i].getName().equalsIgnoreCase(ioc.getValueByName(&quot;field&quot;)))&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; mSet=pd[i].getWriteMethod();&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; mRead=pd[i].getReadMethod();&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }try {&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; mSet.invoke(obj, ioc.getValueByName(&quot;value&quot;));&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; String str=(String)mRead.invoke(obj, null);&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.out.println(str);&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; } catch (IllegalArgumentException e) {// TODO Auto-generated catch block&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; e.printStackTrace();&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; } catch (InvocationTargetException e) {// TODO Auto-generated catch block&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; e.printStackTrace();&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; } catch (InstantiationException e) {// TODO Auto-generated catch block&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; e.printStackTrace();&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; } catch (IllegalAccessException e) {// TODO Auto-generated catch block&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; e.printStackTrace();&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; } catch (IntrospectionException e) {// TODO Auto-generated catch block&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; e.printStackTrace();&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }&#160;&#160;&#160;&#160;&#160;&#160;&#160; }catch(ClassNotFoundException e){&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.out.println(e.toString());&#160;&#160;&#160;&#160;&#160;&#160;&#160; }&#160;&#160;&#160; }}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://javadou.com/ioc-study-233/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spring：IoC，AOP学习</title>
		<link>http://javadou.com/spring-ioc-aop-195/</link>
		<comments>http://javadou.com/spring-ioc-aop-195/#comments</comments>
		<pubDate>Thu, 03 Sep 2009 19:38:00 +0000</pubDate>
		<dc:creator>阿超</dc:creator>
				<category><![CDATA[Spring]]></category>
		<category><![CDATA[aop]]></category>
		<category><![CDATA[ioc]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://javadou.com/spring-ioc-aop-195/</guid>
		<description><![CDATA[1 从http://www.springframework.org下载Spring 
2 用eclipse新建Java项目 
3 建立我们的业务方法接... ]]></description>
			<content:encoded><![CDATA[<p>1 从http://www.springframework.org下载Spring    <br />2 用eclipse新建Java项目     <br />3 建立我们的业务方法接口</p>
<pre class="java">public interface BusinessObject {
  public void doSomething();

public void doAnotherThing();

}</pre>
<p>4 实现业务方法，注意这是的setWords使用了依赖注入，所谓依赖注入就是把配置文件中的字符串什么的在程序运行时“自动”放到我们的程序中来。如果不是这样，我们就只能在代码中固化这些东西，从而违背了面向对象的依赖倒置原则，还有一种满足依赖倒置的方法，即依赖查询，这就是所谓的factory模式，即在代码中请求某种抽象的东西，然后根据配置得到它，但这种办法向对于依赖注入多了对环境的依赖，且代码冗余，EJB的JNDI查询就属于这种。另外我们的Spring配置文件是以bean为核心的，就是我们写的一个类，在XML中描述它的名称、位置和涵盖的内容、关系。</p>
<pre class="java">public class BusinessObjectImpl implements BusinessObject {
  private String words;

public void setWords(String words){

this.words = words;

&#160;&#160;&#160; }

public void doSomething() {

&#160;&#160;&#160;&#160;&#160;&#160;&#160; Log log = LogFactory.getLog(this.getClass());

&#160;&#160;&#160;&#160;&#160;&#160;&#160; log.info(words);

&#160;&#160;&#160; }

public void doAnotherThing() {

&#160;&#160;&#160;&#160;&#160;&#160;&#160; Log log = LogFactory.getLog(this.getClass());

&#160;&#160;&#160;&#160;&#160;&#160;&#160; log.info(&quot;Another thing&quot;);

&#160;&#160;&#160; }

}</pre>
<p>5 建立一个运行方法类，从配置文件spring-beans.xml中读入bo这个类的定义，然后实例化一个对象</p>
<pre class="java">import org.springframework.beans.factory.xml.XmlBeanFactory;
  import org.springframework.core.io.ClassPathResource;

public class Main {

public static void main(String[] args){

&#160;&#160;&#160;&#160;&#160;&#160;&#160; XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource(&quot;spring-beans.xml&quot;));

&#160;&#160;&#160;&#160;&#160;&#160;&#160; BusinessObject bo = (BusinessObject)xbf.getBean(&quot;bo&quot;);

&#160;&#160;&#160;&#160;&#160;&#160;&#160; bo.doSomething();

&#160;&#160;&#160;&#160;&#160;&#160;&#160; bo.doAnotherThing();

&#160;&#160;&#160; }

}</pre>
<p>6 建立一个拦截器类invoke是MethodInterceptor必须实现的方法，表示拦截时的动作，大家仔细体会代码中的含义</p>
<pre class="java">import org.aopalliance.intercept.MethodInterceptor;
  import org.aopalliance.intercept.MethodInvocation;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

public class MyInterceptor implements MethodInterceptor {

private String before, after;

public void setAfter(String after) {

this.after = after;

&#160;&#160;&#160; }

public void setBefore(String before) {

this.before = before;

&#160;&#160;&#160; }

public Object invoke(MethodInvocation invocation) throws Throwable {

&#160;&#160;&#160;&#160;&#160;&#160;&#160; Log log = LogFactory.getLog(this.getClass());

&#160;&#160;&#160;&#160;&#160;&#160;&#160; log.info(before);

&#160;&#160;&#160;&#160;&#160;&#160;&#160; Object rval = invocation.proceed();

&#160;&#160;&#160;&#160;&#160;&#160;&#160; log.info(after);

return rval;

&#160;&#160;&#160; }

}</pre>
<p>7 建立配置文件组织上面的类之间的关系，AOP有切入点和增强这两个重要的概念，把两个概念结合到一起，就是一个在某个方法执行的时候附加执行，切入点表示在哪里附加，增强表示附加什么，配置文件中的myPointcut表示切入点，myInterceptor表示增强的内容，myAdvisor表示增强器，即两者的结合，在bo这个bean中，我们把这个增强器附加到了bo这个bean上。</p>
<pre class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
  &lt;!DOCTYPE beans PUBLIC &quot;-//SPRING//DTD BEAN//EN&quot; &quot;http://www.springframework.org/dtd/spring-beans.dtd&quot;&gt;

&lt;beans&gt;

&lt;bean id=&quot;businessObjectImpl&quot; class=&quot;BusinessObjectImpl&quot;&gt;

&lt;property name=&quot;words&quot;&gt;

&lt;value&gt;正在执行业务方法&lt;/value&gt;

&lt;/property&gt;

&lt;/bean&gt;

&lt;bean id=&quot;myInterceptor&quot; class=&quot;MyInterceptor&quot;&gt;

&lt;property name=&quot;before&quot;&gt;

&lt;value&gt;执行业务方法前&lt;/value&gt;

&lt;/property&gt;

&lt;property name=&quot;after&quot;&gt;

&lt;value&gt;执行业务方法后&lt;/value&gt;

&lt;/property&gt;

&lt;/bean&gt;

&lt;bean id=&quot;myPointcut&quot; class=&quot;org.springframework.aop.support.JdkRegexpMethodPointcut&quot;&gt;

&lt;property name=&quot;patterns&quot;&gt;

&lt;list&gt;

&lt;value&gt;BusinessObject.doSomething&lt;/value&gt;

&lt;/list&gt;

&lt;/property&gt;

&lt;/bean&gt;

&lt;bean id=&quot;myAdvisor&quot; class=&quot;org.springframework.aop.support.DefaultPointcutAdvisor&quot;&gt;

&lt;property name=&quot;pointcut&quot; ref=&quot;myPointcut&quot;/&gt;

&lt;property name=&quot;advice&quot; ref=&quot;myInterceptor&quot;/&gt;

&lt;/bean&gt;

&lt;bean id=&quot;bo&quot; class=&quot;org.springframework.aop.framework.ProxyFactoryBean&quot;&gt;

&lt;property name=&quot;target&quot;&gt;

&lt;ref local=&quot;businessObjectImpl&quot;/&gt;

&lt;/property&gt;

&lt;property name=&quot;proxyInterfaces&quot;&gt;

&lt;value&gt;BusinessObject&lt;/value&gt;

&lt;/property&gt;

&lt;property name=&quot;interceptorNames&quot;&gt;

&lt;list&gt;

&lt;value&gt;myInterceptor&lt;/value&gt;

&lt;value&gt;myAdvisor&lt;/value&gt;

&lt;/list&gt;

&lt;/property&gt;

&lt;/bean&gt;

&lt;/beans&gt;</pre>
<p>8 运行Main类，观察控制台输出结果，重新审查代码，反思为什么会出现这种结果。</p>
]]></content:encoded>
			<wfw:commentRss>http://javadou.com/spring-ioc-aop-195/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>新一代快速注入框架Google Guice使用入门</title>
		<link>http://javadou.com/new-ico-google-guice-59/</link>
		<comments>http://javadou.com/new-ico-google-guice-59/#comments</comments>
		<pubDate>Fri, 21 Aug 2009 11:30:00 +0000</pubDate>
		<dc:creator>阿超</dc:creator>
				<category><![CDATA[Guice]]></category>
		<category><![CDATA[google guice]]></category>
		<category><![CDATA[ioc]]></category>
		<category><![CDATA[注入]]></category>

		<guid isPermaLink="false">http://javadou.com/%e6%96%b0%e4%b8%80%e4%bb%a3%e5%bf%ab%e9%80%9f%e6%b3%a8%e5%85%a5%e6%a1%86%e6%9e%b6google-guice%e4%bd%bf%e7%94%a8%e5%85%a5%e9%97%a8-59/</guid>
		<description><![CDATA[最近公司做一个项目，项目当中用到了强大的Google Guice注入取代了Spring，一直在学习，刚有初步认识拿出来和大家分享下通过范例简单地介绍Google Guice的使用，通过下面的范例我们可以知道，Google Guice的使用非常简... ]]></description>
			<content:encoded><![CDATA[<p>最近公司做一个项目，项目当中用到了强大的Google Guice注入取代了Spring，一直在学习，刚有初步认识拿出来和大家分享下通过范例简单地介绍Google Guice的使用，通过下面的范例我们可以知道，Google Guice的使用非常简单。</p>
<p>Google Guice需要使用JDK上java环境。</p>
<p>下载Google Guice之后，有以下几个文件：</p>
<p>&lt;pre class=&#8221;java&#8221;&gt;<br />
aopalliance.jar<br />
guice-jar<br />
guice-servlet-jar<br />
guice-spring-jar<br />
guice-strutsplugin-jar<br />
&lt;/pre&gt;<br />
本例只使用到guice-jar文件，将其加入到class path中。</p>
<p>下面简单地介绍范例：</p>
<p>范例使用com.google.inject.Module接口实现类</p>
<p>文件名 说明<br />
HelloGuice.java 业务逻辑接口定义文件<br />
HelloGuiceImpl.java 业务逻辑接口实现文件<br />
HelloGuiceModule.java 该文件必须实现com.google.inject.Module接口<br />
TestGuice.java 测试文件</p>
<p>HelloGuice.java<br />
&lt;pre class=&#8221;java&#8221;&gt;<br />
package cn.jcourse.guice;<br />
/**<br />
* @author zhangtao<br />
* HelloGuice接口,用于表达问候<br />
*/<br />
public interface HelloGuice {<br />
public void sayHello();<br />
}<br />
&lt;/pre&gt;<br />
上面接口中，我们定义了一个方法，sayHello，用于向用户问候。这里我只是做演示用，在实际的业务中，业务逻辑很可能不是这么简单。</p>
<p>HelloGuiceImpl.java<br />
&lt;pre class=&#8221;java&#8221;&gt;<br />
package cn.jcourse.guice.impl;<br />
import cn.jcourse.guice.HelloGuice;<br />
/**<br />
* @author zhangtao<br />
* HellGuice实现类<br />
*/<br />
public class HelloGuiceImpl implements HelloGuice {<br />
/* (non-Javadoc)<br />
* @see cn.jcourse.guice.HelloGuice#sayHello()<br />
*/<br />
public void sayHello() {<br />
System.out.println(&#8220;Hello Guice!&#8221;);<br />
}<br />
} &lt;/pre&gt;<br />
该类是HelloGuice接口的实现类，这里我们仅仅是向控制台输出了一个Hello Guice!字符串。</p>
<p>HelloGuiceModule.java<br />
&lt;pre class=&#8221;java&#8221;&gt;<br />
package cn.jcourse.guice;<br />
import cn.jcourse.guice.impl.HelloGuiceImpl;<br />
import com.google.inject.Binder;<br />
import com.google.inject.Module;<br />
/**<br />
* @author zhangtao<br />
* HelloGuice模块<br />
*/<br />
.public class HelloGuiceModule implements Module {<br />
/*<br />
* (non-Javadoc)<br />
*<br />
* @see com.google.inject.Module#configure(com.google.inject.Binder)<br />
*/<br />
public void configure(Binder binder) {<br />
binder.bind(HelloGuice.class).to(HelloGuiceImpl.class);<br />
}<br />
}  &lt;/pre&gt;<br />
上面的代码用于告知Guice将接口和实现类绑定。</p>
<p>TestGuice.java<br />
&lt;pre class=&#8221;java&#8221;&gt;<br />
package cn.jcourse.guice.test;<br />
import cn.jcourse.guice.HelloGuice;<br />
import cn.jcourse.guice.HelloGuiceModule;<br />
import com.google.inject.Guice;<br />
import com.google.inject.Injector;<br />
import junit.framework.TestCase;<br />
/**<br />
* @author zhangtao<br />
* 测试Guice<br />
*/<br />
public class TestGuice extends TestCase {<br />
public void testHelloGuice() {<br />
Injector injector = Guice.createInjector(new HelloGuiceModule());<br />
HelloGuice helloGuice = injector.getInstance(HelloGuice.class);<br />
helloGuice.sayHello();<br />
}<br />
}  &lt;/pre&gt;<br />
上面的代码我们使用JUnit来进行单元测试，这里的代码也相对比较简单。</p>
<p>在编写完上述代码后，我们运行TestGuice类，将会发现它向控制台输出了Hello Guice!。</p>
<p>范例使用Java Annotation</p>
<p>范例，我们自己手工的去配置了绑定关系，当然我们也可以不用那么做。我们可以直接为HelloGuice加上@ImplementedBy注释，而省略掉对com.google.inject.Module的实现。</p>
<p>HelloGuice.java<br />
&lt;pre class=&#8221;java&#8221;&gt;<br />
package cn.jcourse.guice;<br />
import cn.jcourse.guice.impl.HelloGuiceImpl;<br />
import com.google.inject.ImplementedBy;<br />
/**<br />
* @author zhangtao<br />
* HelloGuice接口,用于表达问候<br />
*/<br />
@ImplementedBy(HelloGuiceImpl.class)<br />
public interface HelloGuice {<br />
public void sayHello();<br />
}   &lt;/pre&gt;<br />
这里我们使用了Guice提供的注解，ImplementedBy，表示该接口由HelloGuiceImpl类实现。这样我们就可以不手动的去配置依赖关系。再看看TestGuice.java。</p>
<p>TestGuice.java<br />
&lt;pre class=&#8221;java&#8221;&gt;<br />
package cn.jcourse.guice.test;<br />
import junit.framework.TestCase;<br />
import cn.jcourse.guice.HelloGuice;<br />
import com.google.inject.Guice;<br />
import com.google.inject.Injector;<br />
/**<br />
* @author zhangtao<br />
* 测试Guice<br />
*/<br />
public class TestGuice extends TestCase {<br />
public void testHelloGuice() {<br />
//Injector injector = Guice.createInjector(new HelloGuiceModule());<br />
Injector injector = Guice.createInjector();<br />
HelloGuice helloGuice = injector.getInstance(HelloGuice.class);<br />
helloGuice.sayHello();<br />
}<br />
}  &lt;/pre&gt;<br />
可以看出，我们不需要自己去new一个Module了，Guice会根据我们提供的注解自己来配置依赖关系。</p>
<p>我们运行例子的时候可以看出，它也输出了Hello Guice!到控制台。</p>
]]></content:encoded>
			<wfw:commentRss>http://javadou.com/new-ico-google-guice-59/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
