一、IOC
面向接口编程的思路:
假设现在要写一个模块,用户管理模块:
1.至少要有一个类:User,作为实体类。com.zgy.model.User.java
User类应该具有的属性有:String name , String password
package com.zgy.model;
public class User {
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
2.用户的管理类UserService,通过UserService管理User,主要是业务逻辑
package com.zgy.service;
import com.zgy.dao.UserDAO;
import com.zgy.impl.UserDAOImpl;
import com.zgy.model.User;
public class UserService {
private UserDAO userDAO ;
public void add(User u){
this.userDAO.save(u);
}
public UserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
}
3.UserDAO接口,其中有save(User u)方法,可以存储数据。该类负责与数据库打交道,UserService调用UserDAO,由UserDAO调用User和数据库
package com.zgy.dao;
import com.zgy.model.User;
public interface UserDAO {
public void save(User u);
}
4.UserDAOImpl类实现了UserDAO接口,实现了接口中的save(User u)方法。通过不同的UserDAO接口的实现,可以实现跨数据库的操作。例如:使用MySQL数据库,就可以写一个UserDAOMySQLImpl,使用Oracle数据库也可通过实现UserDAO来完成。这就是面向抽象编程。
package com.zgy.impl;
import com.zgy.dao.UserDAO;
import com.zgy.model.User;
public class UserDAOImpl implements UserDAO{
public void save(User u) {
System.out.println("user saved");
}
}
5.当存在多个模块的时候,比如有老师管理,学生管理,课程管理……这样就会存在不同的DAO。此时可以使用一个大的DAO来管理。此处可以使用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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="u" class="com.zgy.impl.UserDAOImpl">
</bean>
<bean id="userService" class="com.zgy.service.UserService">
<property name="userDAO" ref="u" />
</bean>
</beans>
6.IOC(DI)
由容器来装配对象,比如UserService类中的userDAO对象,它不是手动new出来的对象,而是由容器注入的,这样通过在配置文件中使用不同的配置,就可以实现不同的注入。
<bean id="u" class="com.zgy.impl.UserDAOImpl">
</bean>
<bean id="userService" class="com.zgy.service.UserService">
<property name="userDAO" ref="u" />
</bean>
以上定义了两个bean,第一个bean的含义是,u是一个UserDAOImpl的对象
userService是UserService的对象,该对象含有一个userDAO属性,该属性的值是通过id为u的这个bean来注入的,即userDAO是通过UserDAOImpl来实例化的。
7.编写JUnit测试类
package com.bjsxt.service;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.zgy.dao.UserDAO;
import com.zgy.model.User;
import com.zgy.service.UserService;
public class UserServiceTest {
@Test
public void testAdd() throws Exception {
BeanFactory applicationContext = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService) applicationContext.getBean("userService");
User u = new User();
u.setName("zhangsan");
u.setPassword("zhangsan");
userService.add(u);
}
}
8.分析:
BeanFactory applicationContext = new ClassPathXmlApplicationContext("beans.xml");是读取配置文件的
UserService userService = (UserService) applicationContext.getBean("userService");获取配置文件中的userService这个bean
二、Spring注入类型
1.setter(最常用的方法)
<property name="userDAO" ref="u" />默认使用的就是setter方法
2.构造方法
在UserDAO中增加构造方法
package com.zgy.service;
import com.zgy.dao.UserDAO;
import com.zgy.impl.UserDAOImpl;
import com.zgy.model.User;
public class UserService {
private UserDAO userDAO;
public void add(User u){
this.userDAO.save(u);
}
public UserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
public UserService(UserDAO userDAO) {
super();
this.userDAO = userDAO;
}
}
修改beans.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="u" class="com.zgy.impl.UserDAOImpl">
</bean>
<bean id="userService" class="com.zgy.service.UserService">
<!-- <property name="userDAO" ref="u" /> -->
<constructor-arg>
<ref bean="u"/>
</constructor-arg>
</bean>
</beans>
当构造方法中含有多个参数的时候,可以使用<constructor-arg type="">或者<constructor-arg index="">来分别指定参数的类型或者参数的索引,用于区分不同的参数。
3.接口注入(很少使用)