Spring IOC example one
当从BeanFactory中通过getBean()方法获取一个bean的时候,BeanFactory会经过如下的步骤来构建Bean的实例,这正是实例化Bean的过程:
1、调用Bean的默认构造方法,或者在指定的构造方法,生成bean实例(暂称为instance1);
3、如果Bean的配置文件中注入了Bean属性值,则在instance1基础上进行属性注入形成instance2,这种注入是覆盖性的。
2、如果Bean实现了InitializingBean接口,则调用afterPropertiesSet()方法,来改变或操作instance2,得到instance3;
4、如果Bean的配置文件中指定了init-method="init"属性,则会调用指定的初始化方法,则在instance3的基础上调用初始化方法init(),将对象最终初始化为instance4;当然,这个初始化的名字是任意的。
instance1、2、3、4是一个实例在不同阶段的状态。
先写个IOC的 例子吧
首先建立一个java项目
在这个项目中有三个包 userDao,userManager,client,还有一个xml配置文件,整个项目是针对接口编程的。
首先是dao包
建立一个接口如下
public interface UserDao { public void addUser(String name); }
接着实现这个接口,采用两种方法实现
实现一
public class UserDaoOracleimp implements UserDao { @Override public void addUser(String name) { // TODO Auto-generated method stub System.out.println("implements by oracle"+" "+name); } }
实现二
public class UserDaoSQLimp implements UserDao { @Override public void addUser(String name) { System.out.println("implements by sql"); } }
接着是Manager包,建立接口
public interface UserManager { public void getDao(); }
实现接口
public class UserManagerimp implements UserManager { private UserDao userdao; public UserManagerimp() { super(); } public UserManagerimp(UserDao userdao) { super(); this.userdao = userdao; } public void setUserdao(UserDao userdao) { this.userdao = userdao; } @Override public void getDao() { userdao.addUser("zhang min"); } }
applicationContextXml配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="UserDaoOracleimp" class="com.spring.dao.UserDaoOracleimp"/> <bean id="UserDaoSQLimp" class="com.spring.dao.UserDaoSQLimp"/> <bean id="UserManager" class="com.spring.manager.UserManagerimp"> <property name="userdao" ref="UserDaoSQLimp"/> </bean> </beans>
main函数运行上述例子
public class Client { public static void main(String[] args) { @SuppressWarnings("resource") ApplicationContext factory = new ClassPathXmlApplicationContext("applicationContext.xml"); UserManager userManager = (UserManager) factory.getBean("UserManager"); userManager.getDao(); } }
在上述例子中,当我们在userManager中需要引用userDao时,我们不在需要直接UserDao userdao = new UserDaoSQLimp(); new一个对象,而仅仅是
提供一个setUserdao(UserDao userdao)方法。采用的是set注入方法 在XML中有如下配置
<bean id="UserManager" class="com.spring.manager.UserManagerimp">
<property name="userdao" ref="UserDaoSQLimp"/>
</bean>
对于采用set注入,我们必须提供一个无参构造函数,否则会报如下错误
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'UserManager' defined in class path resource [applicationContext.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.spring.manager.UserManagerimp]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.spring.manager.UserManagerimp.<init>()
当然我们还可以采用构造函数注入的方法 当采用该方法时候,我们需要提供一个带参数的构造函数 如上
public UserManagerimp(UserDao userdao) {
super();
this.userdao = userdao;
}
并且我们在XML中将不再用 <property name="userdao" ref="UserDaoSQLimp"/>标签 而是采用<constructor-arg ref="UserDaoSQLimp"/>