平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中。
spring有多种依赖注入的形式,下面仅介绍spring通过xml进行IOC配置的方式:
-
<span style="font-size: 14px;">package com.bless.springdemo.action;
-
public class SpringAction {
-
//注入对象springDao
-
private SpringDao springDao;
-
//一定要写被注入对象的set方法
-
public void setSpringDao(SpringDao springDao) {
-
this.springDao = springDao;
-
}
-
public void ok(){
-
springDao.ok();
-
}
-
} </span>
-
<!--配置bean,配置后该类由spring管理-->
-
<bean name="springAction" class="com.bless.springdemo.action.SpringAction">
-
<!--(1)依赖注入,配置当前类中相应的属性-->
-
<property name="springDao" ref="springDao"> </property>
-
</bean>
-
<bean name="springDao" class="com.bless.springdemo.dao.impl.SpringDaoImpl"> </bean>
-
public class SpringAction {
-
//注入对象springDao
-
private SpringDao springDao;
-
private User user;
-
-
public SpringAction(SpringDao springDao,User user){
-
this.springDao = springDao;
-
this.user = user;
-
System.out.println("构造方法调用springDao和user");
-
}
-
-
public void save(){
-
user.setName("卡卡");
-
springDao.save(user);
-
}
-
}
-
<!--配置bean,配置后该类由spring管理-->
-
<bean name="springAction" class="com.bless.springdemo.action.SpringAction">
-
<!--(2)创建构造器注入,如果主类有带参的构造方法则需添加此配置-->
-
<constructor-arg ref="springDao"> </constructor-arg>
-
<constructor-arg ref="user"> </constructor-arg>
-
</bean>
-
<bean name="springDao" class="com.bless.springdemo.dao.impl.SpringDaoImpl"> </bean>
-
<bean name="user" class="com.bless.springdemo.vo.User"> </bean>
-
<bean name="springAction" class="com.bless.springdemo.action.SpringAction">
-
<constructor-arg index="0" ref="springDao"> </constructor-arg>
-
<constructor-arg index="1" ref="user"> </constructor-arg>
-
</bean>
-
<constructor-arg type="java.lang.String" ref=""/> <strong>
-
</strong>
-
<span style="font-size:14px;">package com.bless.springdemo.factory;
-
import com.bless.springdemo.dao.FactoryDao;
-
import com.bless.springdemo.dao.impl.FactoryDaoImpl;
-
import com.bless.springdemo.dao.impl.StaticFacotryDaoImpl;
-
-
public class DaoFactory {
-
//静态工厂
-
public static final FactoryDao getStaticFactoryDaoImpl(){
-
return new StaticFacotryDaoImpl();
-
}
-
} </span> <span style="font-size:12px;"> </span>
-
public class SpringAction {
-
//注入对象
-
private FactoryDao staticFactoryDao;
-
-
public void staticFactoryOk(){
-
staticFactoryDao.saveFactory();
-
}
-
//注入对象的set方法
-
public void setStaticFactoryDao(FactoryDao staticFactoryDao) {
-
this.staticFactoryDao = staticFactoryDao;
-
}
-
}
-
<!--配置bean,配置后该类由spring管理-->
-
<bean name="springAction" class="com.bless.springdemo.action.SpringAction" >
-
<!--(3)使用静态工厂的方法注入对象,对应下面的配置文件(3)-->
-
<property name="staticFactoryDao" ref="staticFactoryDao"> </property>
-
</bean>
-
<!--(3)此处获取对象的方式是从工厂类中获取静态方法-->
-
<bean name="staticFactoryDao" class="com.bless.springdemo.factory.DaoFactory" factory-method="getStaticFactoryDaoImpl"> </bean>
-
public class DaoFactory {
-
//实例工厂
-
public FactoryDao getFactoryDaoImpl(){
-
return new FactoryDaoImpl();
-
}
-
}
-
public class SpringAction {
-
//注入对象
-
private FactoryDao factoryDao;
-
-
public void factoryOk(){
-
factoryDao.saveFactory();
-
}
-
public void setFactoryDao(FactoryDao factoryDao) {
-
this.factoryDao = factoryDao;
-
}
-
}
-
<!--配置bean,配置后该类由spring管理-->
-
<bean name="springAction" class="com.bless.springdemo.action.SpringAction">
-
<!--(4)使用实例工厂的方法注入对象,对应下面的配置文件(4)-->
-
<property name="factoryDao" ref="factoryDao"> </property>
-
</bean>
-
-
<!--(4)此处获取对象的方式是从工厂类中获取实例方法-->
-
<bean name="daoFactory" class="com.bless.springdemo.factory.DaoFactory"> </bean>
-
<bean name="factoryDao" factory-bean="daoFactory" factory-method="getFactoryDaoImpl"> </bean>
<bean name="..." class="..." scope="prototype">
--------------------------------------------------------------完--------------------------------------------------------------------
附录:
一 ref local和ref bean
<ref local="xx"/>
用"local"属性指定目标其实是指向同一文件内对应"id"属性值为此"local"值的索引
"local"属性的值必须和目标bean的id属性相同。如果同一文件内没有匹配的元素,xml解析器将提示错误。同样,如果目标在同一XML文件内,使用"local"变量是最好的选择(为了尽可能早地知道错误)
<ref bean="xx"/>
用"bean"属性指定目标bean是最常规的形式,这允许创建索引到任何同一个容器内的bean(无论是否在同一XML 文件中)或者父级的容器内的bean。"bean"属性的值可以和目标bean的"id"属性相同,也可以和目标bean的"name"属性内的一个值相同
可以这么说, <ref bean=""/> 是寻找全局中的 bean; <ref local=""/> 是寻找本 xml 文件中的 bean
<ref> 提供了如下几方面的属性 :
1)bean: 在当前 Spring XML 配置文件中,或者在同一 BeanFactory(ApplicationContext) 中的其他 JavaBean 中 .
2)local: 在当前 Spring XML 配置文件中 . 其依赖的 JavaBean 必须存在于当前 Spring XML 配置 文件中 . 如果借助于 Spring IDE, 则在编译期可以对其依赖的 JavaBean 进行验证。基于 local 方式,开发者能够使用到 XML 本身提供 的优势,而进行验证。
3)parent: 用于指定其依赖的父 JavaBean 定义。
二 xml配置文件中的bean的三种方法
<bean id="itemf" class="cn.itcareers.m03.ItemFactory" /> 是个普通的Bean;
<bean id="item" factory-bean="itemf" factory-method="getItem" />是工厂Bean。
工厂Bean返回的不是一个实例,而是由工厂getItem方法返回的对象。
2.1 最常见,也是缺省,是调用spring的缺省工厂类
spring缺省工厂类:org.springframework.beans.factory.support.DefaultListableBeanFactory
使用其静态方法preInstantiateSingletons()
配置文件:最普通最基本的定义一个普通bean
<bean id="DvdTypeDAOBean" class="com.machome.dvd.impl.DvdTypeDAO" > </bean>
看日志:
2010-5-29 0:48:48 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
2.2 使用用户自定义的工厂类的静态方法进行创建
定义工厂类,返回new实例
-
public class DvdTypeDAOFactory {
-
public static DvdTypeDAO getInstance(){
-
return new DvdTypeDAO();
-
}
-
}
这里只是简单的定义了一个工厂类,你可以定义更复杂的:
比如单例类(提高利用效率),
比如含有ThreadLocal属性的类(多线程下解决线程安全问题)。
另外:spring配置文件中, bean的class不需要new的类,而是设成工厂类,然后后面加factory-method属性
<bean id="DvdTypeDAOBean" class="com.machome.core.impl.DvdTypeDAOFactory" factory-method="getInstance" />
3.3 在 spring 中建立工厂类的 Bean, 然后调用该工厂 bean 建立真正的 bean
-
public class DvdTypeDAOFactory {
-
public DvdTypeDAO getInstance(){
-
return new DvdTypeDAO();
-
}
-
}
spring配置文件中
<bean id="DvdTypeDAOFactoryBean" class="com.machome.core.impl.DvdTypeDAOFactory" />
这个工厂bean还是被spring的DefaultListableBeanFactory. preInstantiateSingletons创建
<bean id="DvdTypeDAOBean" factory-bean="DvdTypeDAOFactoryBean" factory-method="getInstance" />