spring ioc
ioc(控制反转):本来是由应用程序管理的对象之间的依赖关系,现在交给了容器管理,这就叫做控制反转,交给了ioc容器,sring的ioc容器主要使用依赖注入(DI)的方式进行,不需要主动查找,对象的查找,定位,创建全部交给ioc容器管理了。好莱坞原则,"do not call us,we will call you"恰如其分的表达出反转的意味.
Spring ioc 代码
1 需要的jar包:
manager接口:
<span style="font-family:SimHei;font-size:18px;">package com.sxt.manager;
public interface UserManager {
public void add(String name,String password);
}
</span>
manager实现类:
package com.sxt.manager.impl;
import com.sxt.dao.UserDao;
import com.sxt.manager.UserManager;
public class UserManagerImpl implements UserManager {
private UserDao dao;
public void add(String name, String password) {
dao.add(name,password);
}
public UserDao getDao() {
return dao;
}
public void setDao(UserDao dao) {
this.dao = dao;
}
}
DAO:
package com.sxt.dao;
public interface UserDao {
public void add(String name, String password) ;
}
DAO Mysql实现类:
package com.sxt.dao.impl;
import com.sxt.dao.UserDao;
public class MysqlDaoImpl implements UserDao {
public void add(String name, String password) {
System.out.println("MysqlDaoImpl add "+name+" "+password);
}
}
DAO ORACLE实现类:
package com.sxt.dao.impl;
import com.sxt.dao.UserDao;
public class OracleDaoImpl implements UserDao {
public void add(String name, String password) {
System.out.println("OracleDaoImpl add "+name+" "+password);
}
}
最关键配置文件applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="mysqlDaoImpl" class="com.sxt.dao.impl.MysqlDaoImpl"> </bean>
<bean id="oracleDaoImpl" class="com.sxt.dao.impl.OracleDaoImpl"> </bean>
<bean id="userManagerImpl" class="com.sxt.manager.impl.UserManagerImpl">
<property name="dao" ref="oracleDaoImpl"></property>
</bean>
</beans>
定义了三个bean,指向三个类,然后userManagerImpl的bean的属性引用了oracleDaoImpl,即是把oracleDaoImpl的bean通过set方式注入其中,需要实现set方法。
测试类:
package test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.sxt.manager.UserManager;
import junit.framework.TestCase;
public class InjectTest extends TestCase {
BeanFactory factory ;
@Override
protected void setUp() throws Exception {
super.setUp();
factory=new ClassPathXmlApplicationContext("applicationContext.xml");
}
@Override
protected void tearDown() throws Exception {
// TODO Auto-generated method stub
super.tearDown();
}
public void testIoc(){
UserManager userManager=(UserManager)factory.getBean("userManagerImpl");
userManager.add("xx", "yy");
}
}
打印出:
OracleDaoImpl add xx yy
把配置文件改为
<bean id="userManagerImpl" class="com.sxt.manager.impl.UserManagerImpl">
<property name="dao" ref="mysqlDaoImpl"></property>
</bean>
打印出
MysqlDaoImpl add xx yy
还可以通过构造函数的注入,一定要实现构造函数,配置文件如下:
<bean id="userManagerImpl" class="com.sxt.manager.impl.UserManagerImpl">
<constructor-arg ref="oracleDaoImpl" ></constructor-arg>
</bean>
注意set方式注入的时候,一定要实现默认的构造方法,否则该对象不能实例化.
最后还有一种方式可以注入对象,接口的注入,
由于接口注入已经淘汰,以下是摘抄的一端接口注入的代码看看即可。
将客户类所有注入的方法抽取到一个接口中,客户类通过实现这一接口提供注入的方法。为了采取接口注入的方式,需要声明一个额外的接口:
public interface ActorArrangable ...{ void injectGeli(GeLi geli); }
然后,MoAttack实现这个接口并实现接口中的方法:
代码清单 7 MoAttack:通过接口方法注入革离扮演者
public class MoAttack implements ActorArrangable ...{ private GeLi geli; public void injectGeli (GeLi geli) ...{ ① 实现接口方法 this.geli = geli; } public void cityGateAsk() ...{ geli.responseAsk("墨者革离"); } }
代码清单 8 Director:通过接口方法注入革离扮演者
public class Director ...{ public void direct()...{ GeLi geli = new LiuDeHua(); MoAttack moAttack = new MoAttack(); moAttack. injectGeli (geli); moAttack.cityGateAsk(); } }
spring ioc的好处
1:大量减少了Factory和Singleton的数量,使代码层次更加清晰,主要原因是我们不在查找,定位,创建和管理对象之间的关系了,都交给ioc容器了。
2:spring的ioc容器是一个轻量级的容器,没有侵入性,不需要依赖容器api,也不需要实现一些特殊接口。
3:一个合理设计最好避免侵入性.
4 三种注入实现方式的优缺点:
1 接口注入:不提倡的一种方式,会造成侵入性,已经淘汰了。
2 构造方法注入:优点是对象构造完成之后,就已经进入就绪状态,可以马上使用,缺点是对象依赖关系较多,构造参数列表会比较长,造成维护上的不便。构造方法也无法被继承,无法设置默认值.
3 set方法注入:可以被继承,允许有默认值,缺点是对象构造完以后无法马上进入就绪状态。一般项目工作中set方法比较常用。