依赖注入(@H_404_3@Dependencyinjection@H_404_3@)在@H_404_3@Java@H_404_3@的流行框架中得到了广泛的应用,比如@H_404_3@Struts@H_404_3@,@H_404_3@Spring@H_404_3@等等。(@H_404_3@Martin Fowler@H_404_3@写过一篇这个模式的精彩文章,感兴趣的童鞋可以去度娘)在@H_404_3@Fowler@H_404_3@最先提出依赖注入这个术语之前,人们经常用“控制反转”(@H_404_3@inversion ofcontrol@H_404_3@)这个词来描述同样的事情。其实@H_404_3@IOC@H_404_3@的范围比依赖注入的范围更大,@H_404_3@IOC@H_404_3@包括依赖注入和依赖查找,本文主要介绍依赖注入。@H_404_3@
首先看一个情形,有两个类我们姑且叫他们为A@H_404_3@类和B@H_404_3@类,并且A@H_404_3@类依赖于B@H_404_3@类,也就是说A@H_404_3@类中需要调用B@H_404_3@类中资源(方法或者属性)。大致的代码如下@H_404_3@
public class A{ public void importantMethod(){ B b=....//获得一个B的实例 b.usefulMethod(); ... } ... }
A@H_404_3@类必须先获得B@H_404_3@类的一个实例才可以使用B@H_404_3@。也就是说在A@H_404_3@中实例化B@H_404_3@是肯定的,但是这样就加大了A@H_404_3@与B@H_404_3@的耦合,同时大大的削弱了A@H_404_3@类的重用性。@H_404_3@
再来看一个更实际的例子。下面给出的PersistenceManager@H_404_3@类可以用来把对象存入一个数据库@H_404_3@
public class PersistenceManager{ public void store(Object object){ DataSource dataSource=...//获得数据源 try{ Connection connection=dataSource.getConnection(); ...//将数据存入数据库 }catch{ } } }
PersistenceManager@H_404_3@依赖于DataSource@H_404_3@。它必须先获得一个DataSource@H_404_3@才能创建一个Connection@H_404_3@对象来把数据插入到数据库中。在一个JavaEE@H_404_3@应用程序里,获得一个数据源的常用方法是使用JNDI@H_404_3@查询@H_404_3@
DataSource dataSource=null; try{ context=new InitialContext(); dataSource=(DataSource)context.lookup("java:/comp/env/jdbc/myDataSource"); }catch{ }
用于JDNI@H_404_3@名是变化的,所以PersistenceManager@H_404_3@的可重用性就大大降低。所谓“依赖注入”是指把以来关系“注入”到所依赖的类中。具体到PersistenceManager@H_404_3@例子,我们应该把一个DataSource@H_404_3@对象传递给PersistenceManager@H_404_3@,而不是强迫PersistenceManager@H_404_3@去创建一个。具体代码如下@H_404_3@
public class PersistenceManager{ private DataSource dataSource; public PersistenceManager(DataSource dataSource){ this.dataSource=dataSource; } public void store(Objece object){ try{ Connection connection=dataSource.getConnection(); ...//将数据存入数据库 }catch(sqlException e){ } } }
现在,不管是谁想用PersistenceManager@H_404_3@,都必须通过PersistenceManager@H_404_3@类的构造器“注入”一个DataSource@H_404_3@的实例。现在的PersistenceManager@H_404_3@与它将使用的DataSource@H_404_3@实例之间的耦合就大大降低了。@H_404_3@
通过构造器来注入依赖关系是注入方式的一种,依赖关系还可以通过一个setter@H_404_3@方法来注入。回到刚才的PersistenceManager@H_404_3@例子,我们也可以提供一种如下所示的方式:@H_404_3@
public void setDataSource(DataSource dataSource){ this.dataSource=dataSource; }
以上就是 “依赖注入”的核心思想以及代码示例,总之还是那句老话高内聚,低耦合。该做什么做什么不该自己做的事不要做(让别人做好了传递给自己),否则自己责任就太大了,最终得不到高效的复用。@H_404_3@