Ioc是 spring框架的核心,AOP和声明式事务的实现都依赖与ioc实现的基础上;
控制反转(ioc):
控制:指得是不由程序去创建对象,而是由容器去创建对象; 也就是我们平时创建对象一般都是new一个对象,用过hibernate和Struts2的就深有体会,hibernate中的表对象和struts2中的Action都是由容器来创建的;
反转:值得是不由程序来创建对象,而是由程序来接收对象(通过setXXX或者有参的构造方法);
这种通过接收对象的方式叫做依赖注入(di),以此种方式降低耦合度;
既然有反转那么就有正转,就是指由程序本身来创建对象,就是说在一个类中new了一个对象;
来看代码:
在src下的beans.xml配置文件:(说明一下,spring对配置文件的名称与位置并没有特定的要求)
<bean id="mysqlDao" class="com.czy.userdao.MysqlDao"/>
<bean id="mysqlDao" class="com.czy.userdao.MysqlDao"/>
<bean id="userService" class="com.czy.userservice.UserService">
<property name="userDao" ref="mysqlDao"></property>
</bean><!--通过以上配置来使得两个类发生依赖关系-->
public class UserService implements BaseService{
private BaseDao basedao=null;
@Override
public void setUserDao(BaseDao baseDao) {
// TODO Auto-generated method stub
this.basedao=basedao;
}
public BaseDao getUserDao(){
return basedao;
public class MysqlDao implements BaseDao{
public MysqlDao() {
// TODO Auto-generated constructor stub
System.out.println("new mysqldao");
}
@Override
public void sigal() {
// TODO Auto-generated method stub
System.out.println("i am mysqldao");
}
}
public class Mymain {
public static void main(String[] args) {
BeanFactory bf=new ClassPathXmlApplicationContext("beans.xml");
ServiceImp service= (ServiceImp) bf.getBean("service");//使用beans.xml中的id来实例化,也可以使用类.class,但是要保证类是单例,并且无需做类型转换
service.getDao();
}
}
运行结果:
i am mysqldao
这里值得一提的是:BeanFactory是一个接口,我们也可以使用它的子类ApplicationContext,一般推荐使用ApplicationContext,ApplicationContext功能更加强大,并且ApplicationContext实例化后,spring容器中的单例类(singleton Bean)也将会被实例化,这样在程序中,用到这些类的时候直接就可以使用,而不用花费时间去加载,当然,这样一来程序启动时间自然会增加,而BeanFactory就会在调用到单例类时才加载(有点像是懒加载);
<bean id="oracleDao" class="com.czy.userdao.OracleDao"/>//默认是singleton Bean
Bean的作用域:singleton,protorype,request,session,globalsession,application;
格式:<beanid=”” class=”” scope=””/>默认为单例
使用ioc来创建对象的三种方式:
a)通过无参的构造方法(如上)
b)通过有参的构造方法:
public ServiceImp(BaseDao dao) {
// TODO Auto-generated constructor stub
this.dao=dao;
System.out.println(" 赋值完成");
}
只是配置文件中略有不同:
<bean id="mysqlDao" class="com.service.servicedao.MysqlDao"/>
<bean id="oracleDao" class="com.service.servicedao.OracleDao"/>
<bean id="serviceimp" class="com.service.Imp.ServiceImp">
<constructor-arg index="0" ref="mysqlDao"></constructor-arg>
</bean>
注意点:在constructor中,index是从0开始的;0 表示的是一个参数的构造方法
这是来设置值
构造函数、set方法注入两者各有好处:对依赖关系无需变化的Bean,够着注入更好,但是构造函数注入不适用关系复杂的Bean, 那样子构造函数注入反而显得不直观,这种时候使用set更好,需要改变依赖关系也需要存在set方法;
c)通过工厂类来创建对象
public class MysqlFactory {
public static BaseDao createMysql(){
System.out.println("mysql创建成功");
return new MysqlDao();
}
}
<bean id="user" class="com.czy.factory.MysqlFactory" factory-method="createMysql"/>
<bean id="service" class="com.service.Imp.ServiceImp">
<constructor-arg index="0" ref="user"></constructor-arg>
</bean>